protected void RenderObject(CameraContext cameraContext, ShapeCache cache, int shapeIndex) { CreateMessage shape = cache.GetShapeByIndex(shapeIndex); if (CategoriesState != null && !CategoriesState.IsActive(shape.Category)) { return; } MeshEntry meshEntry = cache.GetShapeDataByIndex <MeshEntry>(shapeIndex); Matrix4x4 transform = cache.GetShapeTransformByIndex(shapeIndex); // TODO: (KS) select command buffer for transparent rendering. CommandBuffer renderQueue = cameraContext.OpaqueBuffer; Material material = meshEntry.Material; RenderMesh mesh = meshEntry.Mesh; if (material == null || mesh == null) { return; } Matrix4x4 modelWorld = cameraContext.TesSceneToWorldTransform * transform; // Transform and cull bounds // FIXME: (KS) this really isn't how culling should be performed. Bounds bounds = GeometryUtility.CalculateBounds(new Vector3[] { mesh.MinBounds, mesh.MaxBounds }, modelWorld); if (!GeometryUtility.TestPlanesAABB(cameraContext.CameraFrustumPlanes, bounds)) { return; } if (mesh.HasColours) { material.SetBuffer("_Colours", mesh.ColoursBuffer); } if (mesh.HasNormals) { material.SetBuffer("_Normals", mesh.NormalsBuffer); } // if (mesh.HasUVs) // { // material.SetBuffer("uvs", mesh.UvsBuffer); // } if (material.HasProperty("_Color")) { material.SetColor("_Color", Maths.ColourExt.ToUnity(new Maths.Colour(shape.Attributes.Colour))); } if (material.HasProperty("_Tint")) { material.SetColor("_Tint", Maths.ColourExt.ToUnity(mesh.Tint)); } if (material.HasProperty("_BackColour")) { material.SetColor("_BackColour", Maths.ColourExt.ToUnity(new Maths.Colour(shape.Attributes.Colour))); } // TODO: (KS) Need to derive this from the shape properties. if (mesh.Topology == MeshTopology.Points) { // Set min/max shader values. if (material.HasProperty("_BoundsMin")) { material.SetVector("_BoundsMin", mesh.MinBounds); } if (material.HasProperty("_BoundsMax")) { material.SetVector("_BoundsMax", mesh.MaxBounds); } float pointScale = (meshEntry.DrawScale > 0) ? meshEntry.DrawScale : 1.0f; material.SetFloat("_PointSize", GlobalSettings.PointSize * pointScale); // Colour by height if we have a zero colour value. if (shape.Attributes.Colour == 0) { material.SetColor("_Color", Color.white); material.SetColor("_BackColour", Color.white); switch (CoordinateFrameUtil.AxisIndex(ServerInfo.CoordinateFrame, 2)) { case 0: material.EnableKeyword("WITH_COLOURS_RANGE_X"); break; case 1: material.EnableKeyword("WITH_COLOURS_RANGE_Y"); break; default: case 2: material.EnableKeyword("WITH_COLOURS_RANGE_Z"); break; } } } // Bind vertices and draw. material.SetBuffer("_Vertices", mesh.VertexBuffer); if (mesh.IndexBuffer != null) { renderQueue.DrawProcedural(mesh.IndexBuffer, modelWorld, material, 0, mesh.Topology, mesh.IndexCount); } else { renderQueue.DrawProcedural(modelWorld, material, 0, mesh.Topology, mesh.VertexCount); } }
void RenderPoints(CameraContext cameraContext, ShapeCache cache, int shapeIndex) { CreateMessage shape = cache.GetShapeByIndex(shapeIndex); if (CategoriesState != null && !CategoriesState.IsActive(shape.Category)) { return; } Matrix4x4 modelWorld = cameraContext.TesSceneToWorldTransform * cache.GetShapeTransformByIndex(shapeIndex); PointsComponent points = cache.GetShapeDataByIndex <PointsComponent>(shapeIndex); CommandBuffer renderQueue = cameraContext.OpaqueBuffer; RenderMesh mesh = points.Mesh != null ? points.Mesh.Mesh : null; if (mesh == null) { // No mesh. Debug.LogWarning($"Point cloud shape {shape.ObjectID} missing mesh with ID {points.MeshID}"); return; } if (points.Material == null) { // No mesh. Debug.LogWarning($"Point cloud shape {shape.ObjectID} missing material"); return; } // Check rendering with index buffer? GraphicsBuffer indexBuffer = null; int indexCount = 0; if (mesh.IndexCount > 0 || points.IndexCount > 0) { if ((int)points.IndexCount > 0) { indexBuffer = points.IndexBuffer; indexCount = (int)points.IndexCount; } // We only use the mesh index buffer if the mesh has points topology. // Otherwise we convert to points using vertices as is. else if (mesh.Topology == MeshTopology.Points) { indexBuffer = mesh.IndexBuffer; indexCount = mesh.IndexCount; } } if (mesh.HasColours) { points.Material.SetBuffer("_Colours", mesh.ColoursBuffer); } if (mesh.HasNormals) { points.Material.SetBuffer("_Normals", mesh.NormalsBuffer); } points.Material.SetBuffer("_Vertices", mesh.VertexBuffer); // Set min/max shader values. if (points.Material.HasProperty("_BoundsMin")) { points.Material.SetVector("_BoundsMin", points.Mesh.Mesh.MinBounds); } if (points.Material.HasProperty("_BoundsMax")) { points.Material.SetVector("_BoundsMax", points.Mesh.Mesh.MaxBounds); } float pointScale = (points.PointScale > 0) ? points.PointScale : 1.0f; points.Material.SetFloat("_PointSize", GlobalSettings.PointSize * pointScale); // Colour by height if we have a zero colour value. if (shape.Attributes.Colour == 0) { points.Material.SetColor("_Color", Color.white); points.Material.SetColor("_BackColour", Color.white); switch (CoordinateFrameUtil.AxisIndex(ServerInfo.CoordinateFrame, 2)) { case 0: points.Material.EnableKeyword("WITH_COLOURS_RANGE_X"); break; case 1: points.Material.EnableKeyword("WITH_COLOURS_RANGE_Y"); break; default: case 2: points.Material.EnableKeyword("WITH_COLOURS_RANGE_Z"); break; } } if (mesh.IndexBuffer != null) { renderQueue.DrawProcedural(mesh.IndexBuffer, modelWorld, points.Material, 0, mesh.Topology, mesh.IndexCount); } else { renderQueue.DrawProcedural(modelWorld, points.Material, 0, mesh.Topology, mesh.VertexCount); } }