/// <summary> /// Set the visuals of <pararef name="points"/> to use <paramref name="meshDetails"/>. /// </summary> /// <param name="points">The points object</param> /// <param name="meshDetails">The mesh details.</param> /// <remarks> /// Adds multiple children to <paramref name="points"/> when <paramref name="meshDetails"/> /// contains multiple mesh objects. /// </remarks> protected virtual void SetMesh(PointsComponent points, MeshCache.MeshDetails meshDetails) { ShapeComponent shape = points.GetComponent <ShapeComponent>(); // Clear all children as a hard reset. foreach (Transform child in points.GetComponentsInChildren <Transform>()) { if (child.gameObject != points.gameObject) { child.parent = null; GameObject.Destroy(child.gameObject); } } // Use shared resources if we have no limited indexing. if (points.IndexCount == 0) { // Add children for each mesh sub-sub-part. int partNumber = 0; foreach (Mesh mesh in meshDetails.FinalMeshes) { GameObject partMesh = new GameObject(string.Format("cloud{0}", partNumber)); partMesh.transform.localPosition = meshDetails.LocalPosition; partMesh.transform.localRotation = meshDetails.LocalRotation; partMesh.transform.localScale = meshDetails.LocalScale; partMesh.AddComponent <MeshFilter>().sharedMesh = mesh; MeshRenderer renderer = partMesh.AddComponent <MeshRenderer>(); if (meshDetails.Topology == MeshTopology.Points) { // Use mesh material as is. renderer.material = meshDetails.Material; } else { // Rendering a mesh with non-point topology. Set tha points based material. renderer.material = mesh.normals.Length > 0 ? _litMaterial : _unlitMaterial; } int pointSize = points.PointSize; if (pointSize == 0 && Materials != null) { pointSize = Materials.DefaultPointSize; } renderer.material.SetInt("_PointSize", pointSize); renderer.material.SetInt("_LeftHanded", ServerInfo.IsLeftHanded ? 1 : 0); renderer.material.color = (shape != null) ? shape.Colour : new Color32(255, 255, 255, 255); partMesh.transform.SetParent(points.transform, false); ++partNumber; } } else { // We are going to need to remap the indexing. For this we'll // copy the required vertices from the MeshDetails and create new // meshes with new indices. We could potentially share vertex data, // but this is difficult with the Unity vertex count limit. Mesh[] meshes = meshDetails.Builder.GetReindexedMeshes(points.Indices, MeshTopology.Points); for (int i = 0; i < meshes.Length; ++i) { // Create this mesh piece. bool defaultMaterial = meshDetails.Topology == MeshTopology.Points; Material material = (defaultMaterial) ? meshDetails.Material : _unlitMaterial; if (!defaultMaterial && meshDetails.Builder.Normals.Length != 0) { material = _litMaterial; } GameObject child = new GameObject(); child.AddComponent <MeshFilter>().mesh = meshes[i]; material.SetInt("_PointSize", points.PointSize); material.SetInt("_LeftHanded", ServerInfo.IsLeftHanded ? 1 : 0); child.AddComponent <MeshRenderer>().material = material; child.transform.SetParent(points.transform, false); } } }