//Mesh generation function wrapped by other methods; do not call this one directly static Mesh GenerationOperation(ref GeneratorProps genProps, out ColliderFinishStatus cFin, bool preview) { genProps.VerifyProperties(); //Make sure properties are valid cFin = ColliderFinishStatus.Fail; //Default status PolygonTest polyTest = PolygonTest.TotalTriangles; //Default polygon test //Choose proper polygon test mode if (genProps.polyTestMode == PolygonTestMode.BestGuess) { polyTest = genProps.boxedCorners ? PolygonTest.EdgeQuads : PolygonTest.FaceEdgeQuads; } else if (genProps.polyTestMode == PolygonTestMode.SafeGuess) { polyTest = genProps.boxedCorners ? PolygonTest.TotalQuads : PolygonTest.TotalTriangles; } else { polyTest = (PolygonTest)(genProps.polyTestMode - 2); } GeneratorInstance gi = new GeneratorInstance();//Temporary container for generation data in the static method bool passedPolyTest = false; bool generating = true; int genAttempts = 0; //Generation attempts int reductionType = 0; //0 = plane strips, 1 = top/bottom segments, 2 = corners //Loop is for repeat detail reduction attempts while (generating) { if (gi != null) { gi.ClearData(); //Clear generation data before next attempt } GenerateMesh(ref gi, genProps); //The true mesh generation function if (genProps.bypassPolyTest || preview) { //Skipping polygon testing passedPolyTest = true; generating = false; } else if (genProps.detailReduction == GeneratorProps.DetailReductionMode.None) { //Skipping detail reduction and checking if polygon test was passed passedPolyTest = MeshPolyTest(gi, genProps, polyTest); generating = false; } else if (genProps.detailReductionAttempts > 0) { //Detail reduction process passedPolyTest = MeshPolyTest(gi, genProps, polyTest);//Polygon testing if (genProps.detailReduction == GeneratorProps.DetailReductionMode.All) { //Reduce all detail properties together, one at a time if (genAttempts < genProps.detailReductionAttempts && !passedPolyTest) { switch (reductionType) { case 0: //Place strip reduction genProps.XYDetail = Mathf.Max(0, genProps.XYDetail - 1); genProps.YZDetail = Mathf.Max(0, genProps.YZDetail - 1); genProps.XZDetail = Mathf.Max(0, genProps.XZDetail - 1); break; case 1: //Top and bottom segment reduction genProps.topSegments = Mathf.Max(0, genProps.topSegments - 1); genProps.bottomSegments = Mathf.Max(0, genProps.bottomSegments - 1); break; case 2: //Corner detail reduction genProps.cornerDetails[0] = Mathf.Max(0, genProps.cornerDetails[0] - 1); genProps.cornerDetails[1] = Mathf.Max(0, genProps.cornerDetails[1] - 1); genProps.cornerDetails[2] = Mathf.Max(0, genProps.cornerDetails[2] - 1); genProps.cornerDetails[3] = Mathf.Max(0, genProps.cornerDetails[3] - 1); break; } reductionType = (reductionType + 1) % 3;//Increment to next reduction type for subsequent attempt } else { generating = false; } } else if (genProps.detailReduction == GeneratorProps.DetailReductionMode.LargestFirst) { //Reduce greatest detail property values first if (genAttempts < genProps.detailReductionAttempts && !passedPolyTest) { //Get maximum detail value int maxDetail = Mathf.Max( genProps.XYDetail, genProps.YZDetail, genProps.XZDetail, genProps.topSegments, genProps.bottomSegments, genProps.cornerDetails[0], genProps.cornerDetails[1], genProps.cornerDetails[2], genProps.cornerDetails[3]); //Reduce all detail properties that match the maximum value if (maxDetail == genProps.XYDetail) { genProps.XYDetail = Mathf.Max(0, genProps.XYDetail - 1); } if (maxDetail == genProps.YZDetail) { genProps.YZDetail = Mathf.Max(0, genProps.YZDetail - 1); } if (maxDetail == genProps.XZDetail) { genProps.XZDetail = Mathf.Max(0, genProps.XZDetail - 1); } if (maxDetail == genProps.topSegments) { genProps.topSegments = Mathf.Max(0, genProps.topSegments - 1); } if (maxDetail == genProps.bottomSegments) { genProps.bottomSegments = Mathf.Max(0, genProps.bottomSegments - 1); } if (maxDetail == genProps.cornerDetails[0]) { genProps.cornerDetails[0] = Mathf.Max(0, genProps.cornerDetails[0] - 1); } if (maxDetail == genProps.cornerDetails[1]) { genProps.cornerDetails[1] = Mathf.Max(0, genProps.cornerDetails[1] - 1); } if (maxDetail == genProps.cornerDetails[2]) { genProps.cornerDetails[2] = Mathf.Max(0, genProps.cornerDetails[2] - 1); } if (maxDetail == genProps.cornerDetails[3]) { genProps.cornerDetails[3] = Mathf.Max(0, genProps.cornerDetails[3] - 1); } } else { generating = false; } } else { generating = false; } } else { generating = false; } genAttempts++; if (genAttempts > genProps.detailReductionAttempts) { //Quit detail reduction upon reaching maximum attempts and throw exception generating = false; if (!passedPolyTest) { cFin = ColliderFinishStatus.DetailTimeout; } } } if (passedPolyTest) { cFin = ColliderFinishStatus.Success;//Successful generation after passing polygon test } else if (cFin != ColliderFinishStatus.DetailTimeout) { cFin = ColliderFinishStatus.FailTriCount;//Failed generation due to having to many polygons } return(gi.colMesh); }
//Generates a collision mesh with the indicated properties and status holder //Preview indicates the mesh is used for previewing and not the actual collider component; will bypass polygon testing public static Mesh GenerateCollider(ref GeneratorProps genProps, out ColliderFinishStatus cFin, bool preview) { return(GenerationOperation(ref genProps, out cFin, preview)); }
//Generates a collision mesh with the indicated properties public static Mesh GenerateCollider(ref GeneratorProps genProps) { ColliderFinishStatus cFin = ColliderFinishStatus.Fail; return(GenerationOperation(ref genProps, out cFin, true)); }
//Generates a collision mesh with the indicated properties and status information public static Mesh GenerateCollider(ref GeneratorProps genProps, out ColliderFinishStatus cFin) { return(GenerationOperation(ref genProps, out cFin, false)); }