public static Vector3 PressureDragForce(TriangleData triangleData) { float velocity = triangleData.velocity.magnitude; float velocityReference = velocity; velocity = velocity / velocityReference; Vector3 pressureDragForce = Vector3.zero; if (triangleData.cosTheta > 0f) { float C_PD1 = DebugPhysics.current.C_PD1; float C_PD2 = DebugPhysics.current.C_PD2; float f_P = DebugPhysics.current.f_P; pressureDragForce = -(C_PD1 * velocity + C_PD2 * (velocity * velocity)) * triangleData.area * Mathf.Pow(triangleData.cosTheta, f_P) * triangleData.normal; } else { float C_SD1 = DebugPhysics.current.C_SD1; float C_SD2 = DebugPhysics.current.C_SD2; float f_S = DebugPhysics.current.f_S; pressureDragForce = (C_SD1 * velocity + C_SD2 * (velocity * velocity)) * triangleData.area * Mathf.Pow(Mathf.Abs(triangleData.cosTheta), f_S) * triangleData.normal; } pressureDragForce = CheckForceIsValid(pressureDragForce, "Pressure drag"); return(pressureDragForce); }
void CalcuProbabilityOfTriangles(float total_probability) { triangleDatas = new TriangleData[triangle_totalCount]; for (int i = 0; i < triangle_totalCount; i++) { var t0 = mesh.triangles[i * 3]; var t1 = mesh.triangles[i * 3 + 1]; var t2 = mesh.triangles[i * 3 + 2]; var uv1 = mesh.uv[t0]; var uv2 = mesh.uv[t1]; var uv3 = mesh.uv[t2]; float size = sizeOfTriangles[i]; TriangleData td = new TriangleData(); float density = GetDensityFromTex(uv1, uv2, uv3); float pdf = (density * size) / total_probability; td.index = i; td.pdf = pdf; for (int j = 0; j < i; j++) { td.cdf += triangleDatas[j].pdf; } td.cdf += pdf; triangleDatas[i] = td; } }
// this script loops through certains points on the map. These points are the corners of (big) triangle shaped areas. // It checks which other points are part of that triangle, and [...] does something? // gets the triangleData public static TriangleData Generate(float[,] noise, float heightMultiplier) { int width = noise.GetLength(0); int length = noise.GetLength(1); TriangleData _mesh = new TriangleData(width, length); int pointNr = 0; // The number of the point on the map that will be used to create a traingle for (int w = 0; w < width; w++) { for (int l = 0; l < length; l++) { _mesh.vertices[pointNr] = new Vector3(l, noise[l, w] * heightMultiplier, w); // location of the vertices (same as the waypoints) _mesh.uvMap[pointNr] = new Vector2(l / (float)length, w / (float)width); // the location for the UVmap (percantage based) if (w < width - 1 && l < length - 1) // loop through all points, except the right edge and bottom edge, as they will not be used { _mesh.CreateTriangle(pointNr, pointNr + width + 1, pointNr + width); _mesh.CreateTriangle(pointNr + width + 1, pointNr, pointNr + 1); } pointNr++; } } return(_mesh); }
static void Main() { // Enable Unicode Console.OutputEncoding = Encoding.Unicode; // створення набору тестових трикутників TriangleData[] triangles = new TriangleData[] { GetTriangle(1, 2, 3), GetTriangle(2, 4, 5), GetTriangle(4, 4, 5), GetTriangle(3, 3, 3), GetTriangle(3, 4, 5), GetTriangle(4, 4, 4 * Math.Sqrt(2)) }; // вивід даних for (int i = 0; i < triangles.Length; i++) { Show(triangles[i]); } // delay Console.ReadKey(true); // локальна функція void Show(TriangleData triangle) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(triangle.ToString()); Console.ResetColor(); triangle.ShowInfo(); } }
void AddUnderWaterForces() { float Cf = BoatPhysicsMath.ResistanceCoefficient( water, boat.velocity.magnitude, modifyBoatMesh.CalculateUnderWaterLength()); List <SlammingForceData> slammingForceData = modifyBoatMesh.slammingForceData; CalculateSlammingVelocities(slammingForceData); float boatArea = modifyBoatMesh.boatArea; float boatMass = VisbyData.mass; List <int> indexOfOriginalTriangle = modifyBoatMesh.indexOfOriginalTriangle; for (int i = 0; i < underWaterTriangleData.Count; i++) { TriangleData triangleData = underWaterTriangleData[i]; vector3 forceToAdd = Vector3.zero; forceToAdd += BoatPhysicsMath.BuoyancyForce(water, triangleData); forceToAdd += BoatPhysicsMath.ViscousWaterResistanceForce(water, triangleData, Cf); forceToAdd += BoatPhysicsMath.PressureDragForce(triangleData); int originalTriangleIndex = indexOfOriginalTriangle[i]; slammingForceData slammingData = slammingForceData[originalTriangleIndex]; forceToAdd += boatPhysicsMath.SlammingForce(slammingData, triangleData, boatArea, boatMass); boatRB.addForceAtPosition(forceToAdd, triangleData.center); } }
private bool OneStep(List <TriangleData> toDo) { int index = toDo.Count - 1; TriangleData triangle = toDo[index]; toDo.RemoveAt(index); triangles.Add(triangle); TriangleData t0 = triangle.CreateNeighbour(0, plane, triangles.Count + ".0"); TriangleData t1 = triangle.CreateNeighbour(1, plane, triangles.Count + ".1"); TriangleData t2 = triangle.CreateNeighbour(2, plane, triangles.Count + ".2"); if (t0 != null) { toDo.Add(t0); } if (t1 != null) { toDo.Add(t1); } if (t2 != null) { toDo.Add(t2); } return(toDo.Count > 0); }
public static void SetUV(MaterialData mat, Mesh mesh, UVMapFn mapFn) { List <Vector2> uvs = new List <Vector2>(); for (int i = 0; i < mesh.vertices.Length; ++i) { uvs.Add(Vector2.zero); } for (int i = 0; i < mesh.triangles.Length; i += 3) { int t1 = mesh.triangles[i]; int t2 = mesh.triangles[i + 1]; int t3 = mesh.triangles[i + 2]; TriangleData td = new TriangleData(t1, t2, t3); Vector3 va = mesh.vertices[t1]; Vector3 vb = mesh.vertices[t2]; Vector3 vc = mesh.vertices[t3]; TriangleData.SetX(td, va.x, vb.x, vc.x); TriangleData.SetY(td, va.y, vb.y, vc.y); TriangleData.SetZ(td, va.z, vb.z, vc.z); mapFn(mat, td, uvs); } mesh.SetUVs(0, uvs); }
public static Vector3 CalculateSlammingForce(TriangleData triangle, SlammingForceData slammingData, float slammingForceAmount, float bodyArea, float bodyMass) { //To capture the response of the fluid to sudden accelerations or penetrations //Add slamming if the normal is in the same direction as the velocity (the triangle is not receding from the water) //Also make sure thea area is not 0, which it sometimes is for some reason if (triangle.cosTheta < 0f || slammingData.originalArea <= 0f) { return(Vector3.zero); } //Step 1 - Calculate acceleration //Volume of water swept per second Vector3 dV = slammingData.submergedArea * slammingData.velocity; Vector3 dV_previous = slammingData.previousSubmergedArea * slammingData.previousVelocity; //Calculate the acceleration of the center point of the original triangle (not the current underwater triangle) //But the triangle the underwater triangle is a part of Vector3 accVec = (dV - dV_previous) / (slammingData.originalArea * Time.fixedDeltaTime); //The magnitude of the acceleration float acc = accVec.magnitude; //Step 2 - Calculate slamming force Vector3 F_stop = bodyMass * triangle.velocity * ((2f * triangle.area) / bodyArea); float p = 2f; float acc_max = acc; Vector3 slammingForce = -Mathf.Pow(Mathf.Clamp01(acc / acc_max), p) * triangle.cosTheta * F_stop * slammingForceAmount; return(CheckForceIsValid(slammingForce)); }
public TriangleData CreateNeighbour(int i, Plane[] planes, string name) { if (neighbour[i] != null) { return(null); } VerticeData v0 = this[i]; VerticeData v1 = this[i + 1]; VerticeData v2 = this[i + 2]; Vector3 p2 = v0.pos + v1.pos - v2.pos; bool newPointIsVisible = IsVisible(p2, planes); if (!(newPointIsVisible || v0.isVisible || v1.isVisible)) { return(null); } var n = new TriangleData(this, p[i], p[(i + 1) % 3], p2, name); n[2].isVisible = newPointIsVisible; return(n); }
//Add all forces that act on the squares below the water void AddUnderWaterForces() { //Get all triangles List <TriangleData> underWaterTriangleData = modifyBoatMesh.underWaterTriangleData; for (int i = 0; i < underWaterTriangleData.Count; i++) { //This triangle TriangleData triangleData = underWaterTriangleData[i]; //Calculate the buoyancy force Vector3 buoyancyForce = BuoyancyForce(rhoWater, triangleData); //Add the force to the boat boatRB.AddForceAtPosition(buoyancyForce, triangleData.center); //Debug //Normal Debug.DrawRay(triangleData.center, triangleData.normal * 3f, Color.white); //Buoyancy Debug.DrawRay(triangleData.center, buoyancyForce.normalized * -3f, Color.blue); } }
public static Vector3 CalculateBuoyancyForce(TriangleData triangle, float waterDensity) { Vector3 force = -waterDensity * Physics.gravity.y * triangle.distToWater * triangle.area * triangle.normal; force.x = force.z = 0; return(CheckForceIsValid(force)); }
public override void OnInspectorGUI() { base.OnInspectorGUI(); owner = (target as NavMeshTool); _property = owner?.data; EditorGUILayoutExt.FloatField("地图宽度", _property.endX - _property.startX); EditorGUILayoutExt.FloatField("地图高度", _property.endZ - _property.startZ); if (GUILayout.Button("测试地图大小")) { CreateMapTestMesh(); } if (_property.mapID == -1) { CheckInit(); } EditorGUILayout.Separator(); if (GUILayout.Button("生成寻路数据")) { CreateNavMeshData(); } EditorGUILayout.Separator(); }
private TriangleData ShowTriangleEditUI(TriangleData triangleData) { int v0, v1, v2; EditorGUILayout.LabelField("Triangle " + triangleData.triangleIndex); GUILayout.BeginHorizontal(); v0 = EditorGUILayout.IntField(GUIContent.none, triangleData.vertexId0, GUILayout.Width(30)); v1 = EditorGUILayout.IntField(GUIContent.none, triangleData.vertexId1, GUILayout.Width(30)); v2 = EditorGUILayout.IntField(GUIContent.none, triangleData.vertexId2, GUILayout.Width(30)); if (v0 >= 0 && v0 < meshEditor.vertexData.Count) { triangleData.vertexId0 = v0; } if (v1 >= 0 && v1 < meshEditor.vertexData.Count) { triangleData.vertexId1 = v1; } if (v2 >= 0 && v2 < meshEditor.vertexData.Count) { triangleData.vertexId2 = v2; } GUILayout.EndHorizontal(); return(triangleData); }
public TriangleGlobals(LocalToWorld localToWorld, TriangleData triangleData) { G1 = math.transform(localToWorld.Value, triangleData.P1); G2 = math.transform(localToWorld.Value, triangleData.P2); G3 = math.transform(localToWorld.Value, triangleData.P3); Center = (G1 + G2 + G3) / 3f; }
public TextureBreakModel(TriangleData triangle, TextureController controller, TextureBreakModel parent) { IsSet = false; _triangle = triangle; _controller = controller; _pool = controller.Pool; _parent = parent; _currentVertices = new TriangleVertices(_triangle); Сentroid = _currentVertices.GetCentroid(); _hasChildren = _controller.IsAbleToHaveChildren(_currentVertices); if (_hasChildren) { SetChildren(); } if (_parent == null) { SetVertices(_currentVertices); } }
//Display the mesh that's the mirror public void DisplayMirrorMesh(Mesh mesh, string name, List <TriangleData> trianglesData) { //Move the vertices based on distance to water float timeSinceStart = Time.time; for (int i = 0; i < trianglesData.Count; i++) { TriangleData thisTriangle = trianglesData[i]; //The vertices in TriangleData are global thisTriangle.p1.y -= WaterController.current.DistanceToWater(thisTriangle.p1, timeSinceStart) * 2f; thisTriangle.p2.y -= WaterController.current.DistanceToWater(thisTriangle.p2, timeSinceStart) * 2f; thisTriangle.p3.y -= WaterController.current.DistanceToWater(thisTriangle.p3, timeSinceStart) * 2f; //Flip the triangle because it will be inside out when we mirror the mesh Vector3 tmp = thisTriangle.p2; thisTriangle.p2 = thisTriangle.p3; thisTriangle.p3 = tmp; trianglesData[i] = thisTriangle; } DisplayMesh(mesh, name, trianglesData); }
public void addTriangle(Vector3 a, Vector3 b, Vector3 c) { TriangleData tri = ScriptableObject.CreateInstance <TriangleData>(); tri.create(a, b, c); triangles.Add(tri); }
public VerticeData(Vector3 pos, TriangleData triangle) { this.pos = pos; triangles = new List <TriangleData>() { triangle }; }
void OnDrawGizmos() { //show all normal gizmos in edit mode for (int i = 0; i < data.triangleCount; i++) { TriangleData triangle = data.GetTriangleData(i); Gizmos.DrawRay(transform.TransformPoint(triangle.center), triangle.normal * length); } }
public static void BarkMapping(MaterialData mat, TriangleData triangle, List <Vector2> uvs) { Vector3 a = TriangleData.GetVector(triangle, 0); Vector3 b = TriangleData.GetVector(triangle, 1); Vector3 c = TriangleData.GetVector(triangle, 2); Vector3 normal = Vector3.Cross(a - b, a - c).normalized; Vector2 uva = Vector2.zero; Vector2 uvb = Vector2.zero; Vector2 uvc = Vector2.zero; // Sides are 0, top/bottom is 1. This info should be provided by the // MaterialData object. Won't work for bark materials, will it? // Don't implement this yet. I need to see how MaterialData matures. // MaterialIndex.GetTileIndex(mi, materialData, SIDE); int tile = 0; if (IsAlignedX(normal, axisAlignThreshold)) { uva = ProjectX(a, mat.halfSize, mat.size); uvb = ProjectX(b, mat.halfSize, mat.size); uvc = ProjectX(c, mat.halfSize, mat.size); // Pick a vertex and see if it is a part of the bark tile = (a.x < -(mat.halfSize.x - mat.barkThickness.x)) || (a.x > mat.halfSize.x - mat.barkThickness.x) ? 0 : 1; } if (IsAlignedZ(normal, axisAlignThreshold)) { uva = ProjectZ(a, mat.halfSize, mat.size); uvb = ProjectZ(b, mat.halfSize, mat.size); uvc = ProjectZ(c, mat.halfSize, mat.size); tile = (a.z < -(mat.halfSize.z - mat.barkThickness.x)) || (a.z > mat.halfSize.z - mat.barkThickness.x) ? 0 : 1; } if (IsAlignedY(normal, axisAlignThreshold)) { uva = ProjectY(a, mat.halfSize, mat.size); uvb = ProjectY(b, mat.halfSize, mat.size); uvc = ProjectY(c, mat.halfSize, mat.size); tile = (a.y < -(mat.halfSize.y - mat.barkThickness.y)) || (a.y > mat.halfSize.y - mat.barkThickness.y) ? 2 : 3; } uvs[triangle.indices[0]] = RemapUVCoordToTile(mat, uva, tile); uvs[triangle.indices[1]] = RemapUVCoordToTile(mat, uvb, tile); uvs[triangle.indices[2]] = RemapUVCoordToTile(mat, uvc, tile); }
public static Vector3 BuoyancyForce(float rho, TriangleData triangleData) { Vector3 buoyancyForce = rho * Physics.gravity.y * triangleData.distanceToSurface * triangleData.area * triangleData.normal; buoyancyForce.x = 0f; buoyancyForce.z = 0f; buoyancyForce = CheckForceIsValid(buoyancyForce, "Buoyancy"); return(buoyancyForce); }
// Calculate the current velocity at the center of each triangle of the original boat mesh private void calculateSlammingVelocities() { for (int i = 0; i < slammingForceData.Count; i++) { //Set the new velocity to the old velocity slammingForceData[i].previousVelocity = slammingForceData[i].velocity; //Center of the triangle in world space Vector3 center = transform.TransformPoint(slammingForceData[i].triangleCenter); //Get the current velocity at the center of the triangle slammingForceData[i].velocity = TriangleData.GetTriangleVelocity(rigidbody, center); } }
public bool intersectPt(Vector3 point, Vector3 direction, ref Vector3 r) { pxyz[0] = -1; int length = plotAll(point.x, point.y, point.z, point.x + direction.x, point.y + direction.y, point.z + direction.z, pxyz); if (pxyz[0] == -1) { return(false); } for (int i = 0; i < length; i += 3) { int hash = pxyz[i] + rows * (pxyz[i + 1] + depth * pxyz[i + 2]); //List<GridDataPointer> list = grid[pxyz[i],pxyz[i + 1],pxyz[i + 2]]; if (grid[hash].dataPt.Count > 0) { Vector3 nearestPt = Vector3.zero; float nearestSqDist = float.PositiveInfinity; bool ret = false; for (int j = 0; j < grid[hash].dataPt.Count; j++) { TriangleData dp = grid[hash].dataPt[j]; Vector3[] tPoints = dp.getTransformedPoints(); Vector3 nPt = point + direction; if (TriangleTests.IntersectLineTriangle(ref point, ref nPt, ref tPoints[0], ref tPoints[1], ref tPoints[2], ref r)) { ret = true; float npSqDist = (point - r).sqrMagnitude; if (npSqDist < nearestSqDist) { nearestSqDist = npSqDist; nearestPt = r; } } } if (ret) { r = nearestPt; return(true); } } } return(false); }
// Projects textures along the cardinal axis. // The bark texture is applied to the sides, no // matter how far into the mesh you slice. public static void ProjectionMapping(MaterialData mat, TriangleData triangle, List <Vector2> uvs) { Vector3 a = TriangleData.GetVector(triangle, 0); Vector3 b = TriangleData.GetVector(triangle, 1); Vector3 c = TriangleData.GetVector(triangle, 2); Vector3 normal = Vector3.Cross(a - b, a - c).normalized; Vector2 uva = Vector2.zero; Vector2 uvb = Vector2.zero; Vector2 uvc = Vector2.zero; // Sides are 0, top/bottom is 1. // This info should be provided by the // MaterialData object. // MaterialIndex.GetTileIndex(mi, materialData, SIDE); // Tile 0 is the side with bark int tile = 0; // Check if the normal is within a range of +/- 85 deg // of the world Y axis. if (IsAlignedY(normal, 85f)) { uva = ProjectY(a, mat.halfSize, mat.size); uvb = ProjectY(b, mat.halfSize, mat.size); uvc = ProjectY(c, mat.halfSize, mat.size); // Tile 3 is the edge without bark tile = 3; } // These checks fail when slicing at an angle outside // axisAlignThreshold. Could improve the IsAligned functions // to accept an axis to project along. That way I could // project the texture along the normal of the triangle. // how would that translate to UV coords? if (IsAlignedX(normal, axisAlignThreshold)) { uva = ProjectX(a, mat.halfSize, mat.size); uvb = ProjectX(b, mat.halfSize, mat.size); uvc = ProjectX(c, mat.halfSize, mat.size); } if (IsAlignedZ(normal, axisAlignThreshold)) { uva = ProjectZ(a, mat.halfSize, mat.size); uvb = ProjectZ(b, mat.halfSize, mat.size); uvc = ProjectZ(c, mat.halfSize, mat.size); } uvs[triangle.indices[0]] = RemapUVCoordToTile(mat, uva, tile); uvs[triangle.indices[1]] = RemapUVCoordToTile(mat, uvb, tile); uvs[triangle.indices[2]] = RemapUVCoordToTile(mat, uvc, tile); }
private void SetAsNeighbour(int i0, int i1, TriangleData n) { for (int i = 0; i < 3; ++i) { if (neighbour[i] == null && (p[i] == i0 || p[i] == i1)) { neighbour[i] = n; return; } } Debug.Log("Odd " + name + " doesn't have common vertice with " + n); }
protected override ValidationResult ValidatePropsValues(IDictionary <string, double> figureProps) { var data = new TriangleData { Base = figureProps[TriangleInfo.PropNames.Base], Height = figureProps[TriangleInfo.PropNames.Height] }; var validator = new TriangleDataValidator(); return(validator.Validate(data)); }
public static Vector3 AirResistanceForce(float rho, TriangleData triangleData, float C_air) { if (triangleData.cosTheta < 0f) { return(Vector3.zero); } Vector3 airResistanceForce = 0.5f * rho * triangleData.velocity.magnitude * triangleData.velocity * triangleData.area * C_air; airResistanceForce *= -1f; airResistanceForce = CheckForceIsValid(airResistanceForce, "Air resistance"); return(airResistanceForce); }
void AddUnderWaterForces() { List <TriangleData> underWaterTriangleData = modifyBoatMesh.underWaterTriangleData; for (int i = 0; i < underWaterTriangleData.Count; i++) { TriangleData triangleData = underWaterTriangleData[i]; Vector3 buoyancyForce = BuoyancyForce(rhoWater, triangleData); boat.AddForceAtPosition(buoyancyForce, triangleData.center); Debug.DrawRay(triangleData.center, triangleData.normal * 3f, Color.white); Debug.DrawRay(triangleData.center, buoyancyForce.normalized * -3f, Color.blue); } }
private Vector3 BuoyancyForce(float waterdensity, TriangleData triangleData) { //Buoyancy force is there even if the objects aren't moving //force buoyancy = density * gravity * Volume of fluid //volume = distance to surface * surface area*normal to the surface Vector3 buyoancyForce = waterdensity * Physics.gravity.y * triangleData.distanceToSurface * triangleData.area * triangleData.normal; //we only care about the y force for the floating buyoancyForce.x = 0f; buyoancyForce.z = 0f; return(buyoancyForce); }
void AddAboveWaterForces() { List <TriangleData> aboveWaterTriangleData = modifyBoatMesh.aboveWaterTriangleData; for (int i = 0; i < aboveWaterTriangleData.Count; i++) { TriangleData triangleData = aboveWaterTriangleData[i]; Vector3 forceToAdd = Vector3.zero; forceToAdd += BoatPhysicsMath.AirResistanceForce(rhoAir, triangleData, boatRB.drag); boatRB.AddForceAtPosition(forceToAdd, triangleData.center); } }
private void RebuildBuffer() { List<TriangleInstance> tempInstances = null; lock (m_instances) { tempInstances = new List<TriangleInstance>(m_instances); } var length = tempInstances.Count; if (length != 0) { TriangleData[] data = new TriangleData[length * 3]; for (int i = 0; i < length * 3; i = i + 3) { var instance = tempInstances[i / 3]; var matrix = Matrix4.Identity; data[i] = new TriangleData() { Color = instance.Color, Position = instance.P1 }; data[i + 1] = new TriangleData() { Color = instance.Color, Position = instance.P2 }; data[i + 2] = new TriangleData() { Color = instance.Color, Position = instance.P3 }; } m_bufferSprite.SetData(data, GL.STREAM_DRAW); } m_isDirty = false; }
private void RebuildBuffer() { List<TriangleInstance> tempInstances = null; lock (m_instances) { tempInstances = new List<TriangleInstance>(m_instances); } var length = tempInstances.Count; if (length != 0) { TriangleData[] data = new TriangleData[length * 3]; Parallel.For(0, length, i => { var instance = tempInstances[i]; var matrix = Matrix4.Identity; data[i * 3] = new TriangleData() { Color = instance.ColorP1, Position = instance.P1 }; data[(i * 3) + 1] = new TriangleData() { Color = instance.ColorP2, Position = instance.P2 }; data[(i * 3) + 2] = new TriangleData() { Color = instance.ColorP3, Position = instance.P3 }; }); GL.BindVertexArray(m_vao); m_bufferSprite.SetData(data, GL.STREAM_DRAW); } else { GL.BindVertexArray(m_vao); m_bufferSprite.SetData(null, GL.STREAM_DRAW); } m_isDirty = false; }
private void RebuildBuffer() { //m_bufferSprite.SetData(m_instances.Count*3, GL.STREAM_DRAW); TriangleData[] data = new TriangleData[m_instances.Count*3]; for (int i = 0; i < m_instances.Count*3; i=i+3) { var instance = m_instances[i/3]; //var center = Barycentre(instance, 1, 1, 1); var matrix = Matrix4.Identity; //matrix *= Matrix4.Translate(instance.P1.X, instance.P1.Y, instance.P1.Z); var u = new Vector3( instance.P2.X - instance.P1.X, instance.P2.Y - instance.P1.Y, instance.P2.Z - instance.P1.Z ); var v = new Vector3( instance.P3.X - instance.P1.X, instance.P3.Y - instance.P1.Y, instance.P3.Z - instance.P1.Z ); var normal = new Vector3( u.Y * v.Z - v.Y * u.Z, -(u.X * v.Z - v.X * u.Z), u.X * v.Y - v.X * u.Y); data[i] = new TriangleData() { Color = instance.Color, Transform = matrix, Normal = normal, Position = instance.P1 }; data[i+1] = new TriangleData() { Color = instance.Color, Transform = matrix, Normal = normal, Position = instance.P2 }; data[i+2] = new TriangleData() { Color = instance.Color, Transform = matrix, Normal = normal, Position = instance.P3 }; } m_bufferSprite.SetData(data, GL.STREAM_DRAW); //using (var mapping = m_bufferSprite.Map()) //{ // unsafe // { // TriangleData* data = (TriangleData*)mapping.Address.ToPointer(); // for (int i = 0; i < m_instances.Count*3; i=i+3) // { // var instance = m_instances[i/3]; // //var center = Barycentre(instance, 1, 1, 1); // var matrix = Matrix4.Identity; // //matrix *= Matrix4.Translate(instance.P1.X, instance.P1.Y, instance.P1.Z); // var u = new Vector3( // instance.P2.X - instance.P1.X, // instance.P2.Y - instance.P1.Y, // instance.P2.Z - instance.P1.Z // ); // var v = new Vector3( // instance.P3.X - instance.P1.X, // instance.P3.Y - instance.P1.Y, // instance.P3.Z - instance.P1.Z // ); // var normal = new Vector3( // u.Y * v.Z - v.Y * u.Z, // -(u.X * v.Z - v.X * u.Z), // u.X * v.Y - v.X * u.Y); // data[i] = new TriangleData() // { // Color = new Vector4(1f, 1f, 1f, 1f), // Transform = matrix, // Normal = normal, // Position = instance.P1 // }; // data[i+1] = new TriangleData() // { // Color = new Vector4(1f, 1f, 1f, 1f), // Transform = matrix, // Normal = normal, // Position = instance.P2 // }; // data[i+2] = new TriangleData() // { // Color = new Vector4(1f, 1f, 1f, 1f), // Transform = matrix, // Normal = normal, // Position = instance.P3 // }; // } // } //} m_isDirty = false; }
/// <summary> /// Initializes a new instance of the <see cref="TriangleData" /> struct. /// </summary> /// <param name="data">The triangle itself</param> /// <param name="verts">The list of all the vertices</param> /// <param name="vpoly">The list of the polygon's vertices</param> public TriangleData(TriangleData data, List<Vector3> verts, Vector3[] vpoly, int npoly) { VertexHash0 = data.VertexHash0; VertexHash1 = data.VertexHash1; VertexHash2 = data.VertexHash2; Flags = GetTriFlags(ref data, verts, vpoly, npoly); }
/// <summary> /// Determine which edges of the triangle are part of the polygon /// </summary> /// <param name="t">A triangle.</param> /// <param name="verts">The vertex buffer that the triangle is referencing.</param> /// <param name="vpoly">Polygon vertex data.</param> /// <returns>The triangle's flags.</returns> public static int GetTriFlags(ref TriangleData t, List<Vector3> verts, Vector3[] vpoly, int npoly) { int flags = 0; //the triangle flags store five bits ?0?0? (like 10001, 10101, etc..) //each bit stores whether two vertices are close enough to a polygon edge //since triangle has three vertices, there are three distinct pairs of vertices (va,vb), (vb,vc) and (vc,va) flags |= GetEdgeFlags(verts[t.VertexHash0], verts[t.VertexHash1], vpoly, npoly) << 0; flags |= GetEdgeFlags(verts[t.VertexHash1], verts[t.VertexHash2], vpoly, npoly) << 2; flags |= GetEdgeFlags(verts[t.VertexHash2], verts[t.VertexHash0], vpoly, npoly) << 4; return flags; }