/// <summary> /// Initializes debug render object given the source object of the /// Collide.Mesh component. /// </summary> private GameObject InitializeMeshGivenSourceObject(Collide.Mesh mesh) { if (mesh.SourceObjects.Length == 0) { throw new Exception("Mesh has no source."); } GameObject meshData = new GameObject("MeshData"); foreach (var sub in mesh.SourceObjects) { GameObject subMesh = new GameObject("SubMeshData"); subMesh.transform.parent = meshData.transform; subMesh.transform.localPosition = Vector3.zero; subMesh.transform.localRotation = Quaternion.identity; MeshRenderer renderer = subMesh.AddComponent <MeshRenderer>(); MeshFilter filter = subMesh.AddComponent <MeshFilter>(); filter.sharedMesh = new UnityEngine.Mesh(); RescaleRenderedMesh(mesh, sub, filter); } m_storedLossyScale = mesh.transform.lossyScale; return(meshData); }
/// <summary> /// If no "Node" instance, this method tries to create one /// given the Collide.Shape component in this game object. /// </summary> /// <returns>True if the node was created - otherwise false.</returns> private bool TryInitialize(Shape shape, DebugRenderManager manager) { if (Node != null) { return(false); } Collide.Mesh mesh = shape as Collide.Mesh; HeightField heightField = shape as HeightField; if (mesh != null) { Node = InitializeMesh(mesh); } else if (heightField != null) { Node = InitializeHeightField(heightField); } else { Node = PrefabLoader.Instantiate <GameObject>(PrefabName); Node.transform.localScale = GetShape().GetScale(); } if (Node != null) { var renderers = Node.GetComponentsInChildren <Renderer>(); foreach (var renderer in renderers) { renderer.sharedMaterial = manager.ShapeRenderMaterial; } } return(Node != null); }
/// <summary> /// Use when Collide.Mesh source objects is updated. /// </summary> public static void HandleMeshSource(Collide.Mesh mesh) { if (!IsActiveForSynchronize) { return; } Instance.SynchronizeShape(mesh); }
/// <summary> /// Callback from Collide.Mesh when a new source has been assigned to /// the mesh. /// </summary> /// <param name="mesh">Mesh shape with updated source object.</param> /// <param name="source">Source mesh that has been changed.</param> /// <param name="added">True if source has been added, false if removed.</param> public static void HandleMeshSource(Collide.Mesh mesh, Mesh source, bool added) { var instance = Find(mesh) as ShapeVisualMesh; if (instance != null) { instance.HandleMeshSource(source, added); } }
/// <summary> /// If no "Node" instance, this method tries to create one /// given the Collide.Shape component in this game object. /// </summary> /// <returns>True if the node was created - otherwise false.</returns> private bool TryInitialize(Shape shape, DebugRenderManager manager) { if (Node != null) { return(false); } Collide.Mesh mesh = shape as Collide.Mesh; HeightField heightField = shape as HeightField; Cone cone = shape as Cone; HollowCone hollowCone = shape as HollowCone; HollowCylinder hollowCylinder = shape as HollowCylinder; if (mesh != null) { Node = InitializeMesh(mesh); } else if (heightField != null) { Node = InitializeHeightField(heightField); } else if (hollowCone != null) { Node = new GameObject(PrefabName); Node.AddComponent <MeshRenderer>().sharedMaterial = manager.ShapeRenderMaterial; Node.AddComponent <MeshFilter>().sharedMesh = ShapeVisualHollowCone.GenerateMesh(shape); } else if (hollowCylinder != null) { Node = new GameObject(PrefabName); Node.AddComponent <MeshRenderer>().sharedMaterial = manager.ShapeRenderMaterial; Node.AddComponent <MeshFilter>().sharedMesh = ShapeVisualHollowCylinder.GenerateMesh(shape); } else if (cone != null) { Node = new GameObject(PrefabName); Node.AddComponent <MeshRenderer>().sharedMaterial = manager.ShapeRenderMaterial; Node.AddComponent <MeshFilter>().sharedMesh = ShapeVisualCone.GenerateMesh(shape); } else { Node = PrefabLoader.Instantiate <GameObject>(PrefabName); Node.transform.localScale = GetShape().GetScale(); } if (Node != null) { var renderers = Node.GetComponentsInChildren <Renderer>(); foreach (var renderer in renderers) { renderer.sharedMaterial = manager.ShapeRenderMaterial; } } return(Node != null); }
private void RescaleRenderedMesh(Collide.Mesh mesh, UnityEngine.Mesh source, MeshFilter filter) { if (source == null) { throw new AgXUnity.Exception("Source object is null during rescale."); } Vector3[] vertices = filter.sharedMesh.vertices; if (vertices == null || vertices.Length == 0) { vertices = new Vector3[source.vertexCount]; } int[] triangles = filter.sharedMesh.triangles; if (triangles == null || triangles.Length == 0) { triangles = (int[])source.triangles.Clone(); } if (vertices.Length != source.vertexCount) { throw new AgXUnity.Exception("Shape debug render mesh mismatch."); } Matrix4x4 scaledToWorld = mesh.transform.localToWorldMatrix; Vector3[] sourceVertices = source.vertices; // Transforms each vertex from local to world given scales, then // transforms each vertex back to local again - unscaled. for (int i = 0; i < vertices.Length; ++i) { Vector3 worldVertex = scaledToWorld * sourceVertices[i]; vertices[i] = mesh.transform.InverseTransformDirection(worldVertex); } filter.sharedMesh.vertices = vertices; filter.sharedMesh.triangles = triangles; filter.sharedMesh.RecalculateBounds(); filter.sharedMesh.RecalculateNormals(); }
/// <summary> /// Initializes and returns a game object if the Collide.Shape type /// is of type mesh. Fails if the shape type is different from mesh. /// </summary> /// <returns>Game object with mesh renderer.</returns> private GameObject InitializeMesh(Collide.Mesh mesh) { return(InitializeMeshGivenSourceObject(mesh)); }