protected GridGenerator(ObjectPool objectPool) { this.objectPool = objectPool; Vector3Comparer vector3Comparer = new Vector3Comparer(); loadedObjects = new Dictionary <Vector3, GameObject>(vector3Comparer); }
public void TestBlendShapeExport(string fbxPath) { fbxPath = FindPathInUnitTests(fbxPath); Assert.That(fbxPath, Is.Not.Null); SkinnedMeshRenderer originalSMR, exportedSMR; ExportSkinnedMesh(fbxPath, out originalSMR, out exportedSMR); var originalMesh = originalSMR.sharedMesh; var exportedMesh = exportedSMR.sharedMesh; Assert.IsNotNull(originalMesh); Assert.IsNotNull(exportedMesh); // compare blend shape data Assert.AreNotEqual(originalMesh.blendShapeCount, 0); Assert.AreEqual(originalMesh.blendShapeCount, exportedMesh.blendShapeCount); { var deltaVertices = new Vector3[originalMesh.vertexCount]; var deltaNormals = new Vector3[originalMesh.vertexCount]; var deltaTangents = new Vector3[originalMesh.vertexCount]; var fbxDeltaVertices = new Vector3[exportedMesh.vertexCount]; var fbxDeltaNormals = new Vector3[exportedMesh.vertexCount]; var fbxDeltaTangents = new Vector3[exportedMesh.vertexCount]; for (int bi = 0; bi < originalMesh.blendShapeCount; ++bi) { Assert.That(originalMesh.GetBlendShapeName(bi), Is.EqualTo(exportedMesh.GetBlendShapeName(bi))); Assert.That(originalMesh.GetBlendShapeFrameCount(bi), Is.EqualTo(exportedMesh.GetBlendShapeFrameCount(bi))); int frameCount = originalMesh.GetBlendShapeFrameCount(bi); for (int fi = 0; fi < frameCount; ++fi) { Assert.That(originalMesh.GetBlendShapeFrameWeight(bi, fi), Is.EqualTo(exportedMesh.GetBlendShapeFrameWeight(bi, fi))); originalMesh.GetBlendShapeFrameVertices(bi, fi, deltaVertices, deltaNormals, deltaTangents); exportedMesh.GetBlendShapeFrameVertices(bi, fi, fbxDeltaVertices, fbxDeltaNormals, fbxDeltaTangents); var v3comparer = new Vector3Comparer(); Assert.That(deltaVertices, Is.EqualTo(fbxDeltaVertices).Using <Vector3>(v3comparer), string.Format("delta vertices don't match")); Assert.That(deltaNormals, Is.EqualTo(fbxDeltaNormals).Using <Vector3>(v3comparer), string.Format("delta normals don't match")); Assert.That(deltaTangents, Is.EqualTo(fbxDeltaTangents).Using <Vector3>(v3comparer), string.Format("delta tangents don't match")); } } } }
private void GenerateUnderwaterTriangles() { var comparer = new Vector3Comparer(); for (var index = 0; index < _boatTriangles.Length; index += 3) { var originalMeshIndex = index / 3; var slammingForce = _slammingForces[originalMeshIndex]; slammingForce.PreviousSubmergedArea = slammingForce.SubmergedArea; slammingForce.SubmergedArea = 0; var poly = new List <Vector3>(); var v0 = _boatTriangles[index]; var v1 = _boatTriangles[index + 1]; var v2 = _boatTriangles[index + 2]; poly = poly.Union(WaterIntersection(v0, v1), comparer).ToList(); poly = poly.Union(WaterIntersection(v1, v2), comparer).ToList(); poly = poly.Union(WaterIntersection(v2, v0), comparer).ToList(); // if poly.length == 4 -> split poly into 2 tris switch (poly.Count) { case 4: AnalyzeTriangle(originalMeshIndex, poly[0], poly[1], poly[3]); AnalyzeTriangle(originalMeshIndex, poly[1], poly[2], poly[3]); break; case 3: AnalyzeTriangle(originalMeshIndex, poly[0], poly[1], poly[2]); break; case 0: break; default: throw new InvalidProgramException("Wrong number of verticies in underwater poly."); } } }
// пересчитываем координаты поверхности для участка, затронутого взрывом // для этого берем координаты и диаметр взрыва, режем получившийся участок // на вертикальные слайсы с заранее заданным шагом // и определяем нужную высоту поверхности после взрыва // с учетом осыпания земли, не попавшей внутрь области взрыва public void TerrainHole(GameObject explosion, float explDiam) //Vector3[] terrMap) { Transform expTransf = explosion.GetComponent <Transform>(); bool intersection = false; int rightCorner = 0; int leftCorner = 0; int i = 0; int firstDel = 0; float x1 = terrMap[0].x, x2 = terrMap[1].x; // считаем координаты первого слайса float sliceX = expTransf.position.x - explDiam / 2 - explDiam / holeSliceCount; float maxX = terrMap[terrMap.Length - 1].x; ArrayList holeMap = new ArrayList(); // вычисляем высоту поверхности после взрыва в каждом слайсе for (int j = 0; (j <= holeSliceCount); j++) //выполняем, пока не переберем все слайсы взрыва { sliceX += explDiam / holeSliceCount; // нужно для корректного вычисления высот при взрыве с правого края поверхности if (sliceX > maxX) { sliceX = maxX; j = holeSliceCount; rightCorner--; } // нужно для корректного вычисления высот при взрыве с левого края поверхности if (sliceX < terrMap[0].x) { leftCorner = 1; sliceX = terrMap[0].x; continue; } // вычисляем, какой отрезок поверхности будет обрабатываться в текущем слайсе while (!((x1 <= sliceX) & (x2 >= sliceX))) { i++; x1 = terrMap[i].x; x2 = terrMap[i + 1].x; } // считаем высоту поверхности float ty1 = terrMap[i].y, ty2 = terrMap[i + 1].y; float terrY = ty2 - (ty2 - ty1) * (x2 - sliceX) / (x2 - x1); //уравнение отрезка float sqrt = (float)Math.Sqrt(Math.Abs(Math.Pow(explDiam / 2, 2) - Math.Pow(sliceX - expTransf.position.x, 2))); float sliceY; if (terrY > expTransf.position.y + sqrt) { sliceY = terrY - 2 * sqrt; } else { sliceY = expTransf.position.y - sqrt; //уравнение окружности } if (j == 0) { firstDel = i; //первый элемент для удаления. Последний - i } //не делаем дырку, если взрыв над поверхностью if (terrY > sliceY) { holeMap.Add(new Vector3(sliceX, sliceY)); intersection = true; } else { holeMap.Add(new Vector3(sliceX, terrY)); } } // заменяем пересчитанный участок в карте поверхности if (intersection) { Vector3[] rejectedMap = new Vector3[terrMap.Length - i + firstDel + rightCorner - leftCorner]; Array.Copy(terrMap, 0, rejectedMap, 0, firstDel + 1 - leftCorner); Array.Copy(terrMap, i + 1, rejectedMap, firstDel + 1 - leftCorner, terrMap.Length - i - 1 + rightCorner);// foreach (Vector3 v in rejectedMap) { ; } //Добавляем в мап Vector3[] holeMapArr = (Vector3[])holeMap.ToArray(typeof(Vector3)); terrMap = new Vector3[rejectedMap.Length + holeMapArr.Length]; Array.Copy(rejectedMap, terrMap, rejectedMap.Length); Array.Copy(holeMapArr, 0, terrMap, rejectedMap.Length, holeMapArr.Length); //сортируем результат IComparer vComparer = new Vector3Comparer(); Array.Sort(terrMap, vComparer); //делаем дырку в коллайдере RecalculateTerr(); } }