浏览代码

adding validation and PR test rail addtion

/validation-tool
Wesley Mareovich Smith 4 年前
当前提交
5384838a
共有 23 个文件被更改,包括 1751 次插入6 次删除
  1. 5
      .github/pull_request_template.md
  2. 3
      com.unity.perception/Tests/Editor/Unity.Perception.Editor.Tests.asmdef
  3. 4
      com.unity.perception/Tests/Runtime/Unity.Perception.Runtime.Tests.asmdef
  4. 8
      com.unity.perception/Editor/Validation.meta
  5. 8
      com.unity.perception/Runtime/Validation.meta
  6. 147
      com.unity.perception/Tests/Editor/EditorValidationTests.cs
  7. 11
      com.unity.perception/Tests/Editor/EditorValidationTests.cs.meta
  8. 8
      com.unity.perception/Tests/Runtime/Validation.meta
  9. 318
      com.unity.perception/Editor/Validation/ModelTestUI.cs
  10. 11
      com.unity.perception/Editor/Validation/ModelTestUI.cs.meta
  11. 54
      com.unity.perception/Runtime/Validation/AIContentData.cs
  12. 11
      com.unity.perception/Runtime/Validation/AIContentData.cs.meta
  13. 496
      com.unity.perception/Runtime/Validation/AIContentValidation.cs
  14. 11
      com.unity.perception/Runtime/Validation/AIContentValidation.cs.meta
  15. 535
      com.unity.perception/Runtime/Validation/AIContentValidationLibrary.cs
  16. 11
      com.unity.perception/Runtime/Validation/AIContentValidationLibrary.cs.meta
  17. 13
      com.unity.perception/Tests/Runtime/Validation/RuntimeValidationTests.cs
  18. 11
      com.unity.perception/Tests/Runtime/Validation/RuntimeValidationTests.cs.meta
  19. 81
      com.unity.perception/Tests/Runtime/Validation/TestBase.cs
  20. 11
      com.unity.perception/Tests/Runtime/Validation/TestBase.cs.meta

5
.github/pull_request_template.md


Information on any code, feature, documentation changes here
## Editor / Package versioning:
**Editor Version Target (i.e. 19.3, 20.1)**: 2019.3
**Editor Version Target (i.e. 19.4, 20.1)**: 2019.4
## Dev Testing:
**Tests Added**:

**Test Rail Cases Added/Updated**:
**At Risk Areas**:
**Notes + Expectations**:

- [ ] - Updated changelog
- [ ] - Test Rail Cases

3
com.unity.perception/Tests/Editor/Unity.Perception.Editor.Tests.asmdef


"Unity.Mathematics",
"Unity.Perception.Editor",
"Unity.Collections",
"Unity.Entities",
"Unity.RenderPipelines.Universal.Runtime"
"Unity.Perception.Runtime.Tests"
],
"includePlatforms": [
"Editor"

4
com.unity.perception/Tests/Runtime/Unity.Perception.Runtime.Tests.asmdef


"Unity.Mathematics",
"Unity.Collections",
"Unity.Burst",
"Unity.Entities",
"Unity.RenderPipelines.HighDefinition.Runtime",
"Unity.RenderPipelines.Universal.Runtime"
"Unity.RenderPipelines.HighDefinition.Runtime"
],
"includePlatforms": [],
"excludePlatforms": [],

8
com.unity.perception/Editor/Validation.meta


fileFormatVersion: 2
guid: 3ba213bea2d90794694cd2f5a6adce6a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
com.unity.perception/Runtime/Validation.meta


fileFormatVersion: 2
guid: c202baa8b32f07b4e9d5f928e71d5ee0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

147
com.unity.perception/Tests/Editor/EditorValidationTests.cs


using NUnit.Framework;
using System.Collections.Generic;
using UnityEditor;
namespace UnityEngine.Perception.ContentTests
{
public class EditorValidationTests : ContentTestBaseSetup
{
[Test]
public void AssetsUVDataTests()
{
Assert.IsTrue(tests.UVDataTest(meshFilters.ToArray()), "UV Data contains errors or is empty");
}
[Test]
public void AssetsUVRangeTests()
{
var test = tests.UVRangeTest(meshFilters.ToArray());
Assert.IsTrue(test, string.Format("UV(s) have range test has failed due to coordinates not in a range of 0 , 1"));
}
[Test]
public void AssetsInvertedNormalsTests()
{
var failedMeshfilters = new List<string>();
var test = tests.MeshInvertedNormalsTest(meshFilters.ToArray(), out failedMeshfilters);
foreach (var mesh in failedMeshfilters)
{
Debug.Log(string.Format("{0} mesh has inverted normals", mesh));
}
Assert.IsTrue(test, "Normals are inverted");
}
[Test]
public void AssetsScaleTest()
{
Assert.IsTrue(tests.TestScale(meshRenderers.ToArray()), "Asset scale is outside the bounds");
}
[Test]
public void AssetMeshUnweldedVerts()
{
var fail = new List<string>();
tests.MeshDetectUnWeldedVerts(meshFilters.ToArray(), out fail);
foreach (var mesh in fail)
{
Debug.Log(string.Format("{0} mesh has un-welded vertices", mesh));
}
Assert.AreEqual(0, fail.Count, "Meshes have un-welded vertices!");
}
[Test]
public void AssetTransformsTest()
{
var failedGameObjects = new List<GameObject>();
foreach (var o in selectionLists)
{
var transformsResult = tests.TransformTest(o, out failedGameObjects);
}
foreach (var fail in failedGameObjects)
{
var failedCount = fail.GetComponentsInParent<Component>();
Debug.Log(string.Format("{0} Parent Transforms are not correct", fail.name));
}
Assert.AreEqual(0, failedGameObjects.Count, "GameObjects failed transforms test");
}
[Test]
public void AssetsParentComponentTest()
{
var failedGameObjects = new List<GameObject>();
foreach (var o in selectionLists)
{
var transformsResult = tests.EmptyComponentsTest(o);
if (!transformsResult)
{
failedGameObjects.Add(o);
}
}
foreach (var fail in failedGameObjects)
{
Debug.Log(string.Format("{0} Parent GameObject is not empty", fail.name));
}
Assert.AreEqual(0, failedGameObjects.Count, "Assets Parent GameObjects Contain more then Transform and Metadata components");
}
[Test]
public void AssetPivotPoint()
{
var failed = new List<GameObject>();
foreach (var o in selectionLists)
{
var pivotPoints = tests.AssetCheckPivotPoint(o, out failed);
}
if (failed.Count != 0)
{
foreach (var o in failed)
{
Debug.Log(string.Format("{0} Pivot point is not in the correct position!", o.name));
}
}
Assert.IsEmpty(failed, "Assets pivot point is not in the correct position!");
}
[Test]
public void AssetTexelDensity()
{
var scale = 4;
var targetResolution = 2048;
var failedMeshes = new List<GameObject>();
var texelDensity = tests.AssetTexelDensity(meshFilters.ToArray(), meshRenderers.ToArray(), out failedMeshes, scale, targetResolution);
for (int i = 0; i < failedMeshes.Count; i++)
{
Debug.Log(string.Format("{0}doesn't support 20.48 texel density!", failedMeshes[i].name));
}
Assert.IsTrue(texelDensity, "Assets currently don't support 2048 texel density");
}
[Test]
public void AssetsOpenMeshTest()
{
var failed = new List<string>();
var openMesh = tests.MeshOpenFaceTest(meshFilters.ToArray(), out failed);
if (failed.Count != 0)
{
foreach (var mesh in failed)
{
Debug.Log(string.Format("{0} has open faces in the mesh!", mesh));
}
}
Assert.IsTrue(openMesh, "Assets currently have holes in the Mesh");
}
}
}

11
com.unity.perception/Tests/Editor/EditorValidationTests.cs.meta


fileFormatVersion: 2
guid: f5aa501b7f8ea7643a9e87db785ac439
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
com.unity.perception/Tests/Runtime/Validation.meta


fileFormatVersion: 2
guid: d83e5825e9a96484aa0918f2b6f69247
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

318
com.unity.perception/Editor/Validation/ModelTestUI.cs


using System.Collections.Generic;
using UnityEditor;
using UnityEngine.Perception.Content;
using MenuItem = UnityEditor.MenuItem;
using UnityEngine;
using static UnityEngine.Perception.Content.CharacterValidation;
using System.Linq;
public class AssetValidation : EditorWindow
{
private static string[] toolbarNames = null;
private enum TestResults
{
Inconclusive,
Pass,
Fail,
Running
}
private TestResults testResults = new TestResults();
private ContentValidation contentTests = new ContentValidation();
private int toolbarSelection = 0;
private GameObject selection = null;
private MeshRenderer[] meshRenderers = null;
private MeshFilter[] meshFilters = null;
private Animator animator = null;
private SkinnedMeshRenderer skinnedMeshRenderer = null;
private List<string> failData = new List<string>();
private bool drawFaceRays = false;
private bool drawIssueEdges = false;
private void OnSelectionChange()
{
UpdateSelection();
}
private void OnInspectorUpdate()
{
UpdateSelection();
}
[MenuItem("Window/Content Validation")]
static void Init()
{
toolbarNames = new string[] { "Assets", "UV", "Mesh", "Character", "Data" };
AssetValidation window = (AssetValidation)GetWindow(typeof(AssetValidation));
window.autoRepaintOnSceneChange = true;
window.Show();
}
private void OnGUI()
{
if (selection != null)
{
EditorGUILayout.TextField("Selected Asset : ", selection.name);
GUILayout.BeginHorizontal();
toolbarSelection = GUILayout.Toolbar(toolbarSelection, toolbarNames);
GUILayout.EndHorizontal();
switch (toolbarSelection)
{
case 0:
GUILayout.Label("Asset Validation", EditorStyles.whiteLargeLabel);
GUILayout.Label(string.Format("Validation Result : {0}", testResults), EditorStyles.boldLabel);
if (GUILayout.Button("Validate Scale", GUILayout.Width(130)))
{
testResults = TestResults.Running;
var scaleResult = contentTests.TestScale(meshRenderers);
if (scaleResult)
testResults = TestResults.Pass;
else if (!scaleResult)
testResults = TestResults.Fail;
}
GUILayout.Label("Empty Game Objects Validation", EditorStyles.boldLabel);
if (GUILayout.Button("Validate", GUILayout.Width(130)))
{
testResults = TestResults.Running;
var result = contentTests.EmptyComponentsTest(selection);
if (result)
testResults = TestResults.Pass;
if (!result)
testResults = TestResults.Fail;
}
GUILayout.Label("Transform Validation", EditorStyles.boldLabel);
if (GUILayout.Button("Validate Transform(s)", GUILayout.Width(140)))
{
testResults = TestResults.Running;
var failedObjects = new List<GameObject>();
var transformTest = contentTests.TransformTest(selection, out failedObjects);
if (transformTest && failedObjects.Count == 0)
testResults = TestResults.Pass;
else if (!transformTest || failedObjects.Count > 0)
testResults = TestResults.Fail;
}
break;
case 1:
GUILayout.Label("UV Validation", EditorStyles.whiteLargeLabel);
GUILayout.Label(string.Format("Validation for UV : {0}", testResults), EditorStyles.boldLabel);
if (GUILayout.Button("Validate UV Data", GUILayout.Width(130)))
{
testResults = TestResults.Running;
var uvDataTest = contentTests.UVDataTest(meshFilters);
testResults = TestResults.Running;
if (uvDataTest)
testResults = TestResults.Pass;
if (!uvDataTest)
testResults = TestResults.Fail;
}
if (GUILayout.Button("Validate UV Range", GUILayout.Width(130)))
{
testResults = TestResults.Running;
var uvInvertedTest = contentTests.UVRangeTest(meshFilters);
if (uvInvertedTest)
testResults = TestResults.Pass;
if (!uvInvertedTest)
testResults = TestResults.Fail;
}
if (GUILayout.Button("Validate UV Positive", GUILayout.Width(130)))
{
testResults = TestResults.Running;
var uvPositiveTest = contentTests.UVPositiveTest(meshFilters);
if (uvPositiveTest)
testResults = TestResults.Pass;
if (!uvPositiveTest)
testResults = TestResults.Fail;
}
break;
case 2:
GUILayout.Label("Mesh Validation", EditorStyles.whiteLargeLabel);
GUILayout.Label(string.Format("Validation for Mesh : {0}", testResults), EditorStyles.boldLabel);
drawFaceRays = GUILayout.Toggle(drawFaceRays, "Draw Asset Mesh");
drawIssueEdges = GUILayout.Toggle(drawIssueEdges, "Draw Issue Edges");
var failedMeshes = new List<string>();
var failedVerts = new List<Mesh>();
if (GUILayout.Button("Validate Mesh Normals", GUILayout.Width(160)))
{
testResults = TestResults.Running;
var invertedNormals = contentTests.MeshInvertedNormalsTest(meshFilters, out failedMeshes);
if (invertedNormals)
testResults = TestResults.Pass;
if (!invertedNormals)
testResults = TestResults.Fail;
}
if (GUILayout.Button("Validate Closed Mesh", GUILayout.Width(160)))
{
testResults = TestResults.Running;
var test = contentTests.MeshOpenFaceTest(meshFilters, out failedMeshes, drawFaceRays, drawIssueEdges);
if (test == true)
testResults = TestResults.Pass;
if (!test)
testResults = TestResults.Fail;
}
if (GUILayout.Button("Validate Vertices's", GUILayout.Width(160)))
{
testResults = TestResults.Running;
var test = contentTests.MeshDetectUnWeldedVerts(meshFilters, out failedMeshes);
if (test)
testResults = TestResults.Pass;
if (!test)
testResults = TestResults.Fail;
}
if (GUILayout.Button("Validate for Spikes", GUILayout.Width(160)))
{
testResults = TestResults.Running;
var test = contentTests.MeshDetectSpikes(meshFilters, drawIssueEdges);
if (test)
testResults = TestResults.Pass;
if (!test)
testResults = TestResults.Fail;
}
if (GUILayout.Button("Validate Texel Density", GUILayout.Width(160)))
{
testResults = TestResults.Running;
var failed = new List<GameObject>();
var test = contentTests.AssetTexelDensity(meshFilters, meshRenderers, out failed);
if (test)
testResults = TestResults.Pass;
if (!test)
testResults = TestResults.Fail;
}
if (GUILayout.Button("Validate Pivot Point", GUILayout.Width(160)))
{
testResults = TestResults.Running;
var failed = new List<GameObject>();
var test = contentTests.AssetCheckPivotPoint(selection, out failed);
if (test)
testResults = TestResults.Pass;
if (!test)
testResults = TestResults.Fail;
}
break;
case 3:
GUILayout.Label("Character Validation", EditorStyles.whiteLargeLabel);
GUILayout.Label(string.Format("Validation for Character : {0}", testResults), EditorStyles.whiteLabel);
if (animator != null)
{
GUILayout.Label(string.Format("Character is Human: {0}", animator.avatar.isHuman), EditorStyles.boldLabel);
GUILayout.Label(string.Format("Character is Valid: {0}", animator.avatar.isValid), EditorStyles.boldLabel);
}
drawFaceRays = GUILayout.Toggle(drawFaceRays, "Draw Face Rays");
var failedBones = new Dictionary<HumanBone, bool>();
var failedPose = new List<GameObject>();
if (GUILayout.Button("Validate Bones", GUILayout.Width(160)))
{
testResults = TestResults.Running;
var test = contentTests.CharacterRequiredBones(animator, out failedBones);
if (failedBones.Count > 0)
{
for (int i = 0; i < RequiredBones.Length; i++)
{
for (int b = 0; b < failedBones.Count; b++)
{
var bone = failedBones.ElementAt(i);
var boneKey = bone.Key;
var boneValue = bone.Value;
if (RequiredBones[i] == boneKey.humanName)
{
GUILayout.Label(string.Format("Bone {0}: {1}", RequiredBones[i], "Missing"), EditorStyles.boldLabel);
}
}
}
}
else if (failedBones.Count == 0)
{
GUILayout.Label(string.Format("Required Bones Present : {0}", TestResults.Pass), EditorStyles.whiteLabel);
}
if (test)
testResults = TestResults.Pass;
if (!test)
testResults = TestResults.Fail;
}
if (GUILayout.Button("Validate Pose Data", GUILayout.Width(160)))
{
testResults = TestResults.Running;
var test = contentTests.CharacterPoseData(selection, out failedPose);
if (test)
testResults = TestResults.Pass;
if (!test)
testResults = TestResults.Fail;
}
if (GUILayout.Button("Create Nose and Ears", GUILayout.Width(160)))
{
testResults = TestResults.Running;
var test = contentTests.CharacterCreateNose(selection, animator, skinnedMeshRenderer, drawFaceRays);
if (test)
testResults = TestResults.Pass;
if (!test)
testResults = TestResults.Fail;
}
break;
case 4:
GUILayout.Label("Asset Results", EditorStyles.boldLabel);
break;
}
}
}
private void UpdateSelection()
{
selection = Selection.activeGameObject;
if (selection != null)
{
meshRenderers = selection.GetComponentsInChildren<MeshRenderer>();
meshFilters = selection.GetComponentsInChildren<MeshFilter>();
animator = selection.GetComponentInChildren<Animator>();
skinnedMeshRenderer = selection.GetComponentInChildren<SkinnedMeshRenderer>();
}
}
}

11
com.unity.perception/Editor/Validation/ModelTestUI.cs.meta


fileFormatVersion: 2
guid: aa3cd9e043826d8459b8f2c63ed153c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

54
com.unity.perception/Runtime/Validation/AIContentData.cs


namespace UnityEngine.Perception.Content
{
public class ContentData : MonoBehaviour
{
//UV Count
public int TryGetAssetUVCount(MeshFilter mesh)
{
return mesh.sharedMesh.uv.Length;
}
public void TryGetAssetUVCount(MeshFilter mesh, out int count, out string assetName)
{
assetName = mesh.name;
count = mesh.sharedMesh.uv.Length;
}
//Size bounds
public void TryGetSizeAsset(MeshRenderer mesh, out Vector3 assetSize, out string assetName)
{
assetName = mesh.name;
assetSize = new Vector3(mesh.bounds.size.x, mesh.bounds.size.y, mesh.bounds.size.y);
}
public Vector3 TryGetSizeAsset(MeshRenderer mesh)
{
return new Vector3(mesh.bounds.size.x, mesh.bounds.size.y, mesh.bounds.size.y);
}
//Vertex Count
public void TryGetAssetVertexCount(MeshFilter mesh, out int count, out string assetName)
{
assetName = mesh.name;
count = mesh.sharedMesh.vertexCount;
}
public int TryGetAssetVertexCount(MeshFilter mesh)
{
return mesh.sharedMesh.vertexCount;
}
//Triangles Count for polygon count
public void TryGetAssetPolygonCount(MeshFilter mesh, out int count, out string assetName)
{
assetName = mesh.name;
count = mesh.sharedMesh.triangles.Length / 3;
}
public int TryGetAssetPolygonCount(MeshFilter mesh)
{
return mesh.sharedMesh.triangles.Length / 3;
}
}
}

11
com.unity.perception/Runtime/Validation/AIContentData.cs.meta


fileFormatVersion: 2
guid: 5a82ed528e1016448a8fc750ba7a7b62
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

496
com.unity.perception/Runtime/Validation/AIContentValidation.cs


using System.Collections.Generic;
using static UnityEngine.Perception.Content.GeomertryValidation;
using static UnityEngine.Perception.Content.TextureValidation;
using static UnityEngine.Perception.Content.CharacterValidation;
using System.Linq;
namespace UnityEngine.Perception.Content
{
public class ContentValidation : MonoBehaviour
{
public bool TestScale(MeshRenderer[] meshRenderers, float heightMax = 2.44f, float widthMax = 2.44f, float lengthMax = 2.44f)
{
var heightPass = false;
var widthPass = false;
var lengthPass = false;
float heightMin = 0.01f;
float widthMin = 0.01f;
float lengthMin = 0.01f;
foreach (var meshRenderer in meshRenderers)
{
var height = meshRenderer.bounds.size.y;
var width = meshRenderer.bounds.size.x;
var length = meshRenderer.bounds.size.z;
if (height <= heightMax && height >= heightMin)
{
heightPass = true;
}
if (width <= widthMax && width >= widthMin)
{
widthPass = true;
}
if (length <= lengthMax && length >= lengthMin)
{
lengthPass = true;
}
}
if (heightPass && widthPass && lengthPass)
return true;
return false;
}
public bool TransformTest(GameObject gameObject, out List<GameObject> failedGameObjects)
{
/// Bounding box at Vector.Zero
var componentsParent = gameObject.GetComponents<Component>();
var componentsChild = gameObject.GetComponentsInChildren<Component>();
var posTransformTest = false;
var rotTransformTest = false;
failedGameObjects = new List<GameObject>();
foreach (var com in componentsParent)
{
posTransformTest = false;
rotTransformTest = false;
if (com.GetType() == typeof(Transform))
{
var rotParent = gameObject.transform.rotation;
var pos = com.transform.position;
var rot = rotParent.eulerAngles;
if (pos == Vector3.zero)
{
posTransformTest = true;
}
if ((rot.x > 269) && (rot.x < 271))
rotTransformTest = true;
else if ((rot.x > 89) && (rot.x < 91))
rotTransformTest = true;
if (rotParent == Quaternion.identity)
rotTransformTest = true;
if (!posTransformTest || !rotTransformTest)
failedGameObjects.Add(com.gameObject);
}
}
foreach (var com in componentsChild)
{
posTransformTest = false;
rotTransformTest = false;
if (com.GetType() == typeof(Transform))
{
var pos = com.transform.position;
var rotEuler = com.transform.rotation.eulerAngles;
var rot = com.transform.rotation;
if (pos == Vector3.zero)
{
posTransformTest = true;
}
if ((rotEuler.x > 269) && (rotEuler.x < 271))
rotTransformTest = true;
else if ((rotEuler.x > 89) && (rotEuler.x < 91))
rotTransformTest = true;
if (rot == Quaternion.identity)
rotTransformTest = true;
if (!posTransformTest || !rotTransformTest)
failedGameObjects.Add(com.gameObject);
}
}
if (failedGameObjects.Count == 0)
return true;
return false;
}
public bool EmptyComponentsTest(GameObject selection)
{
var parentComTest = false;
var baseComTest = false;
var parentComponents = selection.GetComponents<Component>();
foreach (var com in parentComponents)
{
var type = com.GetType();
if (type == selection.transform.GetType() || com.name.Contains("MetaData"))
baseComTest = true;
else
baseComTest = false;
}
if (parentComponents.Length <= 2)
{
parentComTest = true;
}
else
{
parentComTest = false;
}
if (parentComTest && baseComTest)
return true;
return false;
}
public bool AssetCheckPivotPoint(GameObject gameObject, out List<GameObject> failed)
{
failed = new List<GameObject>();
var posParent = gameObject.transform.position;
var componentsChild = gameObject.GetComponentsInChildren<Transform>();
Vector3 attachmentPoint = new Vector3();
float comparePoints = 0f;
string[] attachmentPoints = { "base", "lamp", "backplate", "frame", "holder" };
bool attachPointFound = false;
for (int c = 0; c < componentsChild.Length; c++)
{
for (int a = 0; a < attachmentPoints.Length; a++)
{
if (componentsChild[c].name == attachmentPoints[a])
{
attachmentPoint = componentsChild[c].transform.position;
comparePoints = Vector3.Distance(attachmentPoint, posParent);
attachPointFound = true;
}
}
}
if (!attachPointFound)
{
attachmentPoint = Vector3.zero;
comparePoints = Vector3.Distance(attachmentPoint, posParent);
}
if (comparePoints > 0f)
failed.Add(gameObject);
if (failed.Count == 0)
return true;
return false;
}
public bool UVDataTest(MeshFilter[] meshFilters)
{
var uvsNotNull = false;
var uvsData = false;
foreach (var mesh in meshFilters)
{
var uvs = mesh.sharedMesh.uv;
if (uvs != null)
uvsNotNull = true;
if (uvs.Length > 0)
uvsData = true;
}
if (uvsNotNull && uvsData)
return true;
return false;
}
public bool UVRangeTest(MeshFilter[] meshFilters)
{
var failedUvs = new List<Vector2>();
var failedMeshes = new Dictionary<MeshFilter, decimal>();
decimal uvPassPercentage = 0;
foreach (var mesh in meshFilters)
{
var uvs = mesh.sharedMesh.uv;
var uvPassed = 0;
var uvTotal = uvs.Length;
foreach (var uv in uvs)
{
if (uv.x < 0 || uv.x > 1 && uv.y < 0 || uv.y > 1)
{
failedUvs.Add(uv);
}
else
{
uvPassed += 1;
}
}
uvPassPercentage = (decimal)uvPassed / uvTotal;
uvPassPercentage = uvPassPercentage * 100;
failedMeshes.Add(mesh, uvPassPercentage);
if (uvPassPercentage < 20)
{
Debug.Log(string.Format("{0} failed UV range test with a percentage of {1}", mesh.name, uvPassPercentage));
}
}
if (uvPassPercentage < 20)
return false;
return true;
}
public bool UVPositiveTest(MeshFilter[] meshFilters)
{
var failedUvs = new List<Vector2>();
var failedMeshes = new Dictionary<MeshFilter, decimal>();
decimal uvPassPercentage = 0;
foreach (var mesh in meshFilters)
{
var uvs = mesh.sharedMesh.uv;
var uvPassed = 0;
var uvTotal = uvs.Length;
foreach (var uv in uvs)
{
if (uv.x < 0 || uv.y < 0)
{
failedUvs.Add(uv);
}
else
{
uvPassed += 1;
}
}
uvPassPercentage = (decimal)uvPassed / uvTotal;
uvPassPercentage = uvPassPercentage * 100;
failedMeshes.Add(mesh, uvPassPercentage);
}
if (failedMeshes.Count > 0)
return false;
return true;
}
public bool MeshInvertedNormalsTest(MeshFilter[] meshFilters, out List<string> failedMeshFilters)
{
failedMeshFilters = new List<string>();
foreach (var mesh in meshFilters)
{
var normals = mesh.sharedMesh.normals;
foreach (var norm in normals)
{
if (norm.normalized.magnitude < 0)
{
failedMeshFilters.Add(mesh.name);
}
}
}
if (failedMeshFilters.Count == 0)
return true;
else if (failedMeshFilters.Count > 0)
return false;
return false;
}
public bool MeshOpenFaceTest(MeshFilter[] meshFilters, out List<string> failedMesh, bool drawMesh = false, bool drawEdges = false)
{
var edges = new List<MeshEdge>();
failedMesh = new List<string>();
foreach (var mesh in meshFilters)
{
edges = GetMeshEdges(mesh.sharedMesh, drawMesh).DetectOpenEdges(drawEdges);
if (edges.Count != 0)
{
failedMesh.Add(mesh.name);
}
}
if (failedMesh.Count == 0)
return true;
return false;
}
public bool MeshDetectUnWeldedVerts(MeshFilter[] meshFilters, out List<string> failedMesh)
{
failedMesh = new List<string>();
foreach (var mesh in meshFilters)
{
var verts = DetectUnweldedVerts(mesh.sharedMesh, 0.0001f);
if (verts.Count != 0)
{
failedMesh.Add(mesh.name);
}
}
if (failedMesh.Count == 0)
return true;
return false;
}
public bool MeshDetectSpikes(MeshFilter[] meshFilters, bool DebugDraw)
{
var failedMesh = new List<string>();
foreach (var mesh in meshFilters)
{
var edges = GetMeshEdges(mesh.sharedMesh, false).DetectMeshSpikes(DebugDraw);
if (edges.Count != 0)
failedMesh.Add(mesh.name);
}
if (failedMesh.Count == 0)
return true;
return false;
}
public bool AssetTexelDensity(MeshFilter[] meshFilter, MeshRenderer[] meshRenderer, out List<GameObject> failedMeshes, int scale = 4, int targetResolution = 2048)
{
List<TexelDensity> texelDensity = new List<TexelDensity>();
failedMeshes = new List<GameObject>();
for (int i = 0; i < meshRenderer.Length; i++)
{
texelDensity = GetTexelDensity(meshFilter[i], meshRenderer[i], scale, targetResolution);
foreach (var td in texelDensity)
{
if (td.texelDensity != targetResolution / 100)
failedMeshes.Add(meshFilter[i].gameObject);
if (td.tilingValue <= scale)
if (!failedMeshes.Contains(meshFilter[i].gameObject))
failedMeshes.Add(meshFilter[i].gameObject);
}
}
if (failedMeshes.Count != 0)
{
return false;
}
return true;
}
public bool CharacterRequiredBones(Animator animator, out Dictionary<HumanBone, bool> failed)
{
var result = AvatarRequiredBones(animator);
failed = new Dictionary<HumanBone, bool>();
for (int i = 0; i < result.Count; i++)
{
var bone = result.ElementAt(i);
var boneKey = bone.Key;
var boneValue = bone.Value;
if (boneValue != true)
failed.Add(boneKey, boneValue);
}
if (failed.Count == 0)
return true;
return false;
}
public bool CharacterPoseData(GameObject gameObject, out List<GameObject> failedGameObjects)
{
failedGameObjects = new List<GameObject>();
var componentsParent = gameObject.GetComponents<Transform>();
var componentsChild = gameObject.GetComponentsInChildren<Transform>();
for (int p = 0; p < componentsParent.Length; p++)
{
if (componentsParent[p].GetType() == typeof(Transform))
{
var pos = componentsParent[p].transform.position;
var rot = componentsParent[p].transform.rotation.eulerAngles;
if (pos == null || rot == null)
{
failedGameObjects.Add(componentsParent[p].gameObject);
}
}
}
for (int c = 0; c < componentsChild.Length; c++)
{
if (componentsChild[c].GetType() == typeof(Transform))
{
var pos = componentsChild[c].transform.position;
var rot = componentsChild[c].transform.rotation.eulerAngles;
if (pos == null || rot == null)
{
failedGameObjects.Add(componentsChild[c].gameObject);
}
}
}
if (failedGameObjects.Count == 0)
return true;
return false;
}
public bool CharacterCreateNose(GameObject selection, Animator animator, SkinnedMeshRenderer skinnedMeshRenderer, bool drawRays = false)
{
var model = AvatarCreateNose(selection, animator, skinnedMeshRenderer, drawRays);
var childCount = model.transform.childCount;
var nose = false;
var earRight = false;
var earLeft = false;
for (int i = 0; i < childCount; i++)
{
if (model.transform.GetChild(i).name == "head")
{
var modelHead = model.transform.GetChild(i);
var headChildCount = modelHead.transform.childCount;
for (int h = 0; h > headChildCount; h++)
{
var childName = modelHead.transform.GetChild(h).name;
if (childName.Contains("nose"))
nose = true;
if (childName.Contains("earRight"))
earRight = true;
if (childName.Contains("earLeft"))
earLeft = true;
}
}
}
if (nose && earRight && earLeft)
return true;
return false;
}
}
}

11
com.unity.perception/Runtime/Validation/AIContentValidation.cs.meta


fileFormatVersion: 2
guid: 543f5c12a920b31449320b9de408235e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

535
com.unity.perception/Runtime/Validation/AIContentValidationLibrary.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
namespace UnityEngine.Perception.Content
{
public static class GeomertryValidation
{
public struct MeshEdge
{
public Vector3 v1;
public Vector3 v2;
public MeshEdge(Vector3 v1, Vector3 v2)
{
this.v1 = v1;
this.v2 = v2;
}
}
public struct MeshTrianlge
{
public MeshEdge e1;
public MeshEdge e2;
public MeshEdge e3;
public MeshTrianlge(MeshEdge e1, MeshEdge e2, MeshEdge e3)
{
this.e1 = e1;
this.e2 = e2;
this.e3 = e3;
}
}
public static List<MeshEdge> GetMeshEdges(Mesh mesh, bool drawMesh)
{
List<MeshEdge> result = new List<MeshEdge>();
for (int i = 0; i < mesh.triangles.Length; i += 3)
{
var v1 = mesh.vertices[mesh.triangles[i]];
var v2 = mesh.vertices[mesh.triangles[i + 1]];
var v3 = mesh.vertices[mesh.triangles[i + 2]];
result.Add(new MeshEdge(v1, v2));
result.Add(new MeshEdge(v2, v3));
result.Add(new MeshEdge(v3, v1));
if (drawMesh)
{
Debug.DrawLine(v1, v2, Color.green, 30f);
Debug.DrawLine(v1, v3, Color.green, 30f);
Debug.DrawLine(v2, v3, Color.green, 30f);
}
}
return result;
}
public static List<MeshTrianlge> CreateTrianlges(Mesh mesh, bool drawMesh)
{
List<MeshTrianlge> result = new List<MeshTrianlge>();
for (int i = 0; i < mesh.triangles.Length; i += 3)
{
var v1 = mesh.vertices[mesh.triangles[i]];
var v2 = mesh.vertices[mesh.triangles[i + 1]];
var v3 = mesh.vertices[mesh.triangles[i + 2]];
result.Add(new MeshTrianlge(new MeshEdge(v1, v2), new MeshEdge(v2, v3), new MeshEdge(v3, v1)));
if (drawMesh)
{
Debug.DrawLine(v1, v2, Color.green, 30f);
Debug.DrawLine(v1, v3, Color.green, 30f);
Debug.DrawLine(v2, v3, Color.green, 30f);
}
}
return result;
}
public static List<MeshEdge> DetectOpenEdges(this List<MeshEdge> Edges, bool drawMesh)
{
List<MeshEdge> result = Edges;
for (int i = result.Count - 1; i > 0; i--)
{
for (int n = i - 1; n >= 0; n--)
{
if (result[i].v1 == result[n].v2 && result[i].v2 == result[n].v1)
{
// shared edge so remove both
result.RemoveAt(i);
result.RemoveAt(n);
i--;
break;
}
}
}
if (drawMesh)
{
if (result.Count > 0)
{
for (int e = 0; e < result.Count; e++)
{
Debug.DrawLine(result[e].v1, result[e].v2, Color.blue, 30f);
}
}
}
return result;
}
public static List<MeshEdge> SortEdges(this List<MeshEdge> Edges)
{
List<MeshEdge> result = new List<MeshEdge>(Edges);
for (int i = 0; i < result.Count - 2; i++)
{
MeshEdge e = result[i];
for (int n = i + 1; n < result.Count; n++)
{
MeshEdge a = result[n];
if (e.v2 == a.v1)
{
if (n == i + 1)
break;
result[n] = result[i + 1];
result[i + 1] = a;
break;
}
}
}
return result;
}
public static List<Vector3> DetectUnweldedVerts(Mesh mesh, float distance)
{
List<Vector3> result = mesh.vertices.ToList();
for (int i = result.Count - 1; i > 0; i--)
{
for (int p = i - 1; p >= 0; p--)
{
var m = mesh.vertices[i];
var a = mesh.vertices[p];
var factor = Vector3.Distance(m, a);
if (factor > distance || factor != 0)
{
result.Remove(m);
}
}
}
return result;
}
public static List<MeshEdge> DetectMeshSpikes(this List<MeshEdge> Edges, bool DebugDraw)
{
/// TODO: Doesn't support simple object i.e. a cube because cube all edges z's outside of the bounds
/// Can possibly do this by checking each triangle and the angles within to see if it contains a 90 degree
List<MeshEdge> result = Edges;
List<MeshEdge> spikes = new List<MeshEdge>();
for (int i = 0; i < result.Count; i++)
{
var v1 = result[i].v1;
var v2 = result[i].v2;
var zDiff = v1.z - v2.z;
var yDiff = v1.y - v2.y;
var xDiff = v1.x - v2.x;
if (zDiff > 0.0500 || zDiff < -0.0500)
{
spikes.Add(result[i]);
if(DebugDraw)
Debug.DrawLine(v1, v2, Color.red, 30f);
}
}
return spikes;
}
}
public static class TextureValidation
{
public struct TexelDensity
{
public double texelDensity;
public double tilingValue;
public TexelDensity(double texelDensity, double tilingValue)
{
this.texelDensity = texelDensity;
this.tilingValue = tilingValue;
}
}
public static List<TexelDensity> GetTexelDensity(MeshFilter meshFilter, MeshRenderer meshRenderer, float scale, int targetResolution)
{
// Correct TD for an object is meter x pixel per meter / texture Resolution = tiling value
// Find TD is pixel / 100cm = TD
List <TexelDensity> result = new List<TexelDensity>();
List<Vector2> uvs = meshFilter.sharedMesh.uv.ToList();
var assetWorldSize = meshRenderer.bounds.size;
// Place a texture, although might need to just make the texture 2048
Texture2D testTexture = new Texture2D(targetResolution, targetResolution);
testTexture.wrapMode = TextureWrapMode.Repeat;
testTexture.filterMode = FilterMode.Bilinear;
testTexture.anisoLevel = 1;
AssetDatabase.CreateAsset(testTexture, "Assets/testTexture.renderTexture");
var path = AssetDatabase.GetAssetPath(testTexture);
var test = (Texture2D)AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D));
if(meshRenderer.sharedMaterial != null)
meshRenderer.sharedMaterial.mainTexture = test;
int textureheight = meshRenderer.sharedMaterial.mainTexture.height;
int texturewidth = meshRenderer.sharedMaterial.mainTexture.width;
Vector2 uvSize = new Vector2();
float uvScale = 0;
// Scale UV's to scale input
for (int i = 0; i < uvs.Count; i++)
{
// UVs support a texel density of 2048x2048px to 4'0''x4'0''
uvs[i] = new Vector2(uvs[i].x * scale, uvs[i].y * scale);
if (i == 0)
{
uvSize = uvs[i];
}
else
{
if (uvs[i].x > uvs[i - 1].x)
uvSize.x = uvs[i].x;
if (uvs[i].y > uvs[i - 1].y)
uvSize.y = uvs[i].y;
}
}
// Calculate tile map to see if it is supported as whole number
// Calculate TD and check to make sure it is supported version of 20.48 or other rez
uvScale = uvSize.x;
double texelDensity = textureheight / 100.0;
double tilingValue = uvScale * (texelDensity * 100) / textureheight;
result.Add(new TexelDensity(texelDensity, tilingValue));
return result;
}
}
public static class CharacterValidation
{
public static string[] RequiredBones =
{
"Head",
"Hips",
"Spine",
"LeftUpperArm",
"LeftLowerArm",
"LeftHand",
"RightUpperArm",
"RightLowerArm",
"RightHand",
"LeftUpperLeg",
"LeftLowerLeg",
"LeftFoot",
"RightUpperLeg",
"RightLowerLeg",
"RightFoot",
};
public static Dictionary<HumanBone, bool> AvatarRequiredBones(Animator animator)
{
var result = new Dictionary<HumanBone, bool>();
var human = animator.avatar.humanDescription.human;
var totalBones = 0;
for(int h = 0; h < human.Length; h++)
{
for (int b = 0; b < RequiredBones.Length; b++)
{
if(human[h].humanName == RequiredBones[b])
{
var bone = new HumanBone();
if (human[h].boneName != null)
{
bone.boneName = human[h].boneName;
totalBones = totalBones = +1;
result.Add(bone, true);
}
else
{
result.Add(bone, false);
}
}
}
}
return result;
}
public static GameObject AvatarCreateNose (GameObject selection, Animator animator, SkinnedMeshRenderer skinnedMeshRenderer, bool drawRays = false)
{
var human = animator.avatar.humanDescription.human;
var skeleton = animator.avatar.humanDescription.skeleton;
var verticies = skinnedMeshRenderer.sharedMesh.vertices;
var head = animator.GetBoneTransform(HumanBodyBones.Head);
var leftEye = animator.GetBoneTransform(HumanBodyBones.RightEye);
var rightEye = animator.GetBoneTransform(HumanBodyBones.LeftEye);
var faceCenter = Vector3.zero;
var earCenter = Vector3.zero;
var nosePos = Vector3.zero;
var earRightPos = Vector3.zero;
var earLeftPos = Vector3.zero;
var distanceCheck = 1f;
var eyeDistance = Vector3.Distance(leftEye.position, rightEye.position);
var directionLeft = Quaternion.AngleAxis(-45, -leftEye.right) * -leftEye.up;
var directionRight = Quaternion.AngleAxis(-45, rightEye.right) * -rightEye.up;
var rayHead = new Ray();
var rayLeftEye = new Ray();
var rayRightEye = new Ray();
var noseRayFor = new Ray();
var rayNoseBack = new Ray();
var rayEarLeft = new Ray();
var rayEarRight = new Ray();
var foundRightEar = false;
var foundLeftEar = false;
rayLeftEye.origin = leftEye.position;
rayLeftEye.direction = directionLeft * eyeDistance;
rayRightEye.origin = rightEye.position;
rayRightEye.direction = directionRight * eyeDistance;
for (double i = 0; i < distanceCheck; i += 0.01)
{
var point = Convert.ToSingle(i);
var pointR = rayRightEye.GetPoint(point);
var pointL = rayLeftEye.GetPoint(point);
var distanceX = Math.Abs(pointR.x - pointL.x);
var distanceY = Math.Abs(pointR.y - pointL.y);
if (distanceX < 0.01 && distanceY < 0.01 )
{
faceCenter = pointR;
}
}
rayHead.origin = head.position;
rayHead.direction = Vector3.up * distanceCheck;
noseRayFor.origin = faceCenter;
noseRayFor.direction = Vector3.forward * distanceCheck;
rayNoseBack.origin = faceCenter;
rayNoseBack.direction = Vector3.back * distanceCheck;
for (double i = 0; i < distanceCheck; i += 0.01)
{
var point = Convert.ToSingle(i);
var pointH = rayHead.GetPoint(point);
var pointF = rayNoseBack.GetPoint(point);
var distanceZ = Math.Abs(pointH.z - pointF.z);
if (distanceZ < 0.01)
{
earCenter = pointF;
}
}
for (int v = 0; v < verticies.Length; v++)
{
for (double c = eyeDistance / 2; c < distanceCheck; c += 0.001)
{
var point = Convert.ToSingle(c);
var pointNoseRay = noseRayFor.GetPoint(point);
var pointVert = verticies[v];
var distHeadZ = Math.Abs(pointNoseRay.z - pointVert.z);
var distHeadX = Math.Abs(pointNoseRay.x - pointVert.x);
if (distHeadZ < 0.0001 && distHeadX < 0.001)
{
nosePos = pointNoseRay;
Debug.Log("Found Nose: " + nosePos);
}
if(nosePos == Vector3.zero)
{
if (distHeadZ < 0.001 && distHeadX < 0.001)
{
nosePos = pointNoseRay;
Debug.Log("Found Nose: " + nosePos);
}
}
}
}
rayEarRight.origin = earCenter;
rayEarRight.direction = Vector3.right * distanceCheck;
rayEarLeft.origin = earCenter;
rayEarLeft.direction = Vector3.left * distanceCheck;
for (int v = 0; v < verticies.Length; v++)
{
for (double c = eyeDistance / 2; c < distanceCheck; c += 0.001)
{
var point = Convert.ToSingle(c);
var pointEarRight = rayEarRight.GetPoint(point);
var pointEarLeft = rayEarLeft.GetPoint(point);
var pointVert = verticies[v];
var distEarRightY = Math.Abs(pointEarRight.y - pointVert.y);
var distEarRightX = Math.Abs(pointEarRight.x - pointVert.x);
var distEarLeftY = Math.Abs(pointEarLeft.y - pointVert.y);
var distEarLeftX = Math.Abs(pointEarLeft.x - pointVert.x);
if (distEarRightY < 0.001 && distEarRightX < 0.0001)
{
earRightPos = pointEarRight;
foundRightEar = true;
}
if (distEarLeftY < 0.001 && distEarLeftX < 0.0001)
{
earLeftPos = pointEarLeft;
foundLeftEar = true;
}
if (!foundRightEar)
{
if (distEarRightY < 0.002 && distEarRightX < 0.001)
{
earRightPos = pointEarRight;
}
}
if (!foundLeftEar)
{
if (distEarLeftY < 0.002 && distEarLeftX < 0.001)
{
earLeftPos = pointEarLeft;
}
}
}
}
var earLeftCheck = Vector3.Distance(earLeftPos, earCenter);
var earRightCheck = Vector3.Distance(earRightPos, earCenter);
var eyeCenterDistance = eyeDistance + 0.01f;
if (earLeftCheck > eyeCenterDistance)
{
earLeftPos.x = (-eyeDistance);
}
if (earRightCheck > eyeCenterDistance)
{
earRightPos.x = eyeDistance;
}
if(drawRays)
{
DebugDrawRays(30f, distanceCheck, rightEye, leftEye, head, rayRightEye, rayLeftEye, faceCenter, earCenter);
}
return CreateNewCharacterPrefab(selection, nosePos, earRightPos, earLeftPos);
}
public static void DebugDrawRays(float duration, float distanceCheck, Transform rightEye, Transform leftEye, Transform head,Ray rayRightEye, Ray rayLeftEye, Vector3 faceCenter, Vector3 earCenter)
{
Debug.DrawLine(rightEye.position, leftEye.position, Color.magenta, duration);
Debug.DrawRay(rayLeftEye.origin, rayLeftEye.direction, Color.green, duration);
Debug.DrawRay(rayRightEye.origin, rayRightEye.direction, Color.blue, duration);
Debug.DrawRay(faceCenter, Vector3.forward * distanceCheck, Color.cyan, duration);
Debug.DrawRay(faceCenter, Vector3.back, Color.cyan, duration);
Debug.DrawRay(head.position, Vector3.up, Color.red, duration);
Debug.DrawRay(earCenter, Vector3.right, Color.blue, duration);
Debug.DrawRay(earCenter, Vector3.left, Color.green, duration);
}
public static GameObject CreateNewCharacterPrefab(GameObject selection, Vector3 nosePosition, Vector3 earRightPosition, Vector3 earLeftPosition)
{
var root = (GameObject)PrefabUtility.InstantiatePrefab(selection);
List<Transform> children = new List<Transform>();
root.GetComponentsInChildren(children);
foreach(var child in children)
{
if (child.name == "head")
{
if (nosePosition != Vector3.zero)
{
var nose = new GameObject();
nose.transform.position = nosePosition;
nose.name = "nose";
nose.transform.SetParent(child);
}
if (earRightPosition != Vector3.zero)
{
var earRight = new GameObject();
earRight.transform.position = earRightPosition;
earRight.name = "earRight";
earRight.transform.SetParent(child);
}
if (earLeftPosition != Vector3.zero)
{
var earLeft = new GameObject();
earLeft.transform.position = earLeftPosition;
earLeft.name = "earLeft";
earLeft.transform.SetParent(child);
}
}
}
var model = PrefabUtility.SaveAsPrefabAsset(root, "Assets/" + root.name + ".prefab");
return model;
}
}
}

11
com.unity.perception/Runtime/Validation/AIContentValidationLibrary.cs.meta


fileFormatVersion: 2
guid: 46e8e04cee4511049ab69310afd5f50f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

13
com.unity.perception/Tests/Runtime/Validation/RuntimeValidationTests.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine.Perception.Content;
using UnityEngine.TestTools;
using NUnit.Framework;
namespace UnityEngine.Perception.ContentTests
{
public class RuntimeValidationTests : ContentTestBaseSetup
{
}
}

11
com.unity.perception/Tests/Runtime/Validation/RuntimeValidationTests.cs.meta


fileFormatVersion: 2
guid: 9a64fa29765ea6147a1804421f556d17
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

81
com.unity.perception/Tests/Runtime/Validation/TestBase.cs


using NUnit.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine.Perception.Content;
namespace UnityEngine.Perception
{
public class ContentTestBaseSetup : MonoBehaviour
{
public static List<GameObject> selectionLists = new List<GameObject>();
public static List<MeshRenderer> meshRenderers = new List<MeshRenderer>();
public static List<MeshFilter> meshFilters = new List<MeshFilter>();
public static List<string> assets = new List<string>();
public TestHelpers testHelpers;
public AIContentTests tests;
[SetUp]
public void Setup()
{
tests = new AIContentTests();
testHelpers = new TestHelpers();
selectionLists = new List<GameObject>();
testHelpers.AssetListCreation();
}
[TearDown]
public void TearDown()
{
selectionLists.Clear();
}
}
public class TestHelpers : ContentTestBaseSetup
{
public void AssetListCreation()
{
assets = AssetDatabase.GetAllAssetPaths().Where(o => o.EndsWith(".fbx", StringComparison.OrdinalIgnoreCase)).ToList();
foreach (string o in assets)
{
var asset = AssetDatabase.LoadAssetAtPath<GameObject>(o);
if (asset != null)
selectionLists.Add(asset);
}
foreach (var gameObj in selectionLists)
{
var meshRender = gameObj.GetComponentsInChildren<MeshRenderer>();
var meshFilter = gameObj.GetComponentsInChildren<MeshFilter>();
foreach (var renderer in meshRender)
{
meshRenderers.Add(renderer);
}
foreach (var filter in meshFilter)
{
meshFilters.Add(filter);
}
}
}
public static IEnumerator SkipFrame(int frames)
{
Debug.Log(string.Format("Skipping {0} frames.", frames));
for (int f = 0; f < frames; f++)
{
yield return null;
}
}
public static IEnumerator SkipFrame()
{
yield return SkipFrame(1);
}
}
}

11
com.unity.perception/Tests/Runtime/Validation/TestBase.cs.meta


fileFormatVersion: 2
guid: 7b53ac303673fa243b11391f8528de10
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存