Zed-Unity插件代码注释——ZEDPointCloudManager.cs——点云显示

Zed-Unity插件代码注释——ZEDPointCloudManager.cs

引言

由于项目的需求,需要在混合现实里面获得现实世界中一些物品的位置。ZED相机的双目相机提供了点云的数据,因此自己需要在unity中获得这些数据并进行实际需求的操作。
上个礼拜基本上把ZED-unity插件的原生接口代码通读了一遍,一方面是对整个SDK有了系统的了解,一方面是对C# 语言、Unity语言、这类产品的代码架构有了一定的了解。 而接下来正式转移到实际任务中的代码实践。
插件中提供了一个点云的显示示例,这篇文章先对这个示例的了解做一个简单的记录。代码注释等,下一篇再来考虑如何通过自己的代码来获得自己想要的点云的数据。
由于时间精力的限制,有一些可能觉得自己以后不怎么用的到的 但是现在又不懂的东西,我没有去分析它,但是在相应地方会指出说自己不懂,如果有人会的话,麻烦顺带解答一下。

基础环境

略(2020-09-01 20.46)

ZEDPointCloudManager.cs脚本介绍

  • 脚本位置:
    在这里插入图片描述
  • 脚本功能:
    这个脚本是一个mono的子类,在里面有update()、Aware()等unity的函数。 是一个数据显示的示例脚本,是教开发者如何在unity中实时显示zed相机点云的。
    -脚本使用:
    这个脚本相当于一个脚本组件,需要放置在unity场景中的GameObject上才能运行,脚本对宿主(我自己把组件挂在的对象称为宿主)没有要求。
    脚本要求另外一个脚本组件“ZEDManager.cs”也挂在某个宿主身上。
  • 代码结构:
    在这里插入图片描述
    该脚本比较短,也就388行。内容比较少,这边就不详细说了。直接看代码里面的注释吧。

代码(注释后)

//======= Copyright (c) Stereolabs Corporation, All rights reserved. ===============

using UnityEngine;

/*
 * Editor:Lance
 * 注释时间:初次  2020-09-01 17.18
 */
/// <summary>
/// Displays the point cloud of the real world in front of the camera.
/// Can be attached to any GameObject in a scene, but requires a ZEDManager component to exist somewhere.
/// 镜头前显示现实世界的点云。
/// 可以附加到场景中的任何GameObject,但需要ZEDManager组件存在于某个地方。
/// </summary>
public class ZEDPointCloudManager : MonoBehaviour
{
    
    
    /// <summary>
    /// Set to a camera if you do not want that camera to see the point cloud.
    /// 如果您不希望该摄像机看到点云,则设置为摄像机。
    /// 不希望这个相机看到点云
    /// Editor Lance:这个是什么意思呢,是说设置一个新的虚拟相机,这个相机看不到点云对象?
    /// </summary>
    [Tooltip("Set to a camera if you do not want that camera to see the point cloud. ")]
    public Camera hiddenObjectFromCamera;


    /// <summary>
    /// Instance of the ZEDManager interface
    /// ZEDManager界面的实例,后面应该是要将外部的zedmanager赋值给下面这个变量才对
    /// </summary>
    public ZEDManager zedManager = null;


    /// <summary>
    /// Material used to display the point cloud. Usually Mat_ZED_PointCloud.
    /// 用于显示点云的材质。通常为Mat_ZED_PointCloud。
    /// </summary>
    public Material mat;

    /// <summary>
    /// Number of points displayed. Usually equal to the width * height of the ZED's resolution (eg. 1280 * 720).
    /// 显示的点数。通常等于ZED分辨率的宽度*高度(例如1280 * 720)。
    /// </summary>
    private int numberPoints = 0;


    /// <summary>
    /// zed Camera controller by zedManager
    /// zedManager的zed相机控制器
    /// </summary>
    private sl.ZEDCamera zed = null;

    /// <summary>
    /// Texture that holds the 3D position of the points.
    /// 保持点的3D位置的纹理。
    /// </summary>
    private Texture2D XYZTexture; //Editor Lance:点云纹理,纹理数据与zed的点云数据格式不同,不是一个矩阵

    /// <summary>
    /// Texture that holds the colors of each point.
    /// 保留每个点的颜色的纹理
    /// </summary>
    private Texture2D colorTexture; //Editor Lance:彩色图像的纹理

    /// <summary>
    /// Temporary copy/buffer of the XYZTexture to stop the point cloud in a defined moment.
    /// XYZTexture的临时副本/缓冲区,用于在定义的时刻停止点云。
    /// </summary>
    private RenderTexture XYZTextureCopy = null; //Editor Lance:渲染的纹理对象是什么东西,就是一个临时的纹理变量吧

    /// <summary>
    /// Temporary copy/buffer of the ColorTexture to stop the point cloud in a defined moment.
    /// ColorTexture的临时副本/缓冲区,用于在定义的瞬间停止点云。
    /// </summary>
    private RenderTexture ColorTextureCopy = null;

    /// <summary>
    /// Cached property index of _Position shader property, so we only look it up once. Do not use.
    /// _Position shader属性的缓存属性索引,因此我们只查找一次。不使用。
    /// </summary>
    /// Editor Lance: int?用法  https://www.cnblogs.com/firstcsharp/archive/2011/12/11/2283797.html
    private static int? _positionid;

    /// <summary>
    /// Returns the property index of the _Position property, and looks it up if it hasn't been looked up yet.
    /// 返回_Position属性的属性索引,如果尚未查找,则查找它。
    /// </summary>
    private static int positionID
    {
    
    
        get
        {
    
    
            if (_positionid == null)
            {
    
    
                _positionid = Shader.PropertyToID("_Position"); //
            }

            return (int) _positionid;
        }
    }

    /// <summary>
    /// Cached property index of the _ColorTex shader property, so we only look it up once. Use colorTexID instead.
    /// _ColorTex着色器属性的缓存属性索引,因此我们只查找一次。请改用colorTexID。
    /// </summary>
    private static int? _colortexid;

    /// <summary>
    /// Returns the property index of the _ColorTex property, which is the RGB color texture from the ZED.
    /// 返回_ColorTex属性的属性索引,该属性索引是ZED中的RGB颜色纹理。
    /// </summary>
    private static int colorTexID
    {
    
    
        get
        {
    
    
            if (_colortexid == null)
            {
    
    
                _colortexid = Shader.PropertyToID("_ColorTex");
            }

            return (int) _colortexid;
        }
    }

    /// <summary>
    /// Cached property index of _XYZTex shader property, so we only look it up once. Use xyzTexID instead.
    /// _XYZTex着色器属性的缓存属性索引,因此我们只查找一次。请改用xyzTexID。
    /// </summary>
    private static int? _xyztexid;

    /// <summary>
    /// Returns the property index of the _XYZTex property, which is the XYZ position of each pixel relative to the ZED.
    /// 返回_XYZTex属性的属性索引,该索引是每个像素相对于ZED的XYZ位置。
    /// </summary>
    private static int xyzTexID
    {
    
    
        get
        {
    
    
            if (_xyztexid == null)
            {
    
    
                _xyztexid = Shader.PropertyToID("_XYZTex");
            }

            return (int) _xyztexid;
        }
    }

    /// <summary>
    /// Whether the point cloud should be visible or not.
    /// 点云是否应该可见。
    /// </summary>
    [Tooltip("Whether the point cloud should be visible or not.点云是否应该可见。 ")]
    public bool display = true;

    /// <summary>
    /// Whether to update the point cloud.
    /// If false, the point cloud will display the content of the temp textures from the last update.
    /// 是否更新点云。 如果为false,则点云将显示上一次更新的临时纹理的内容。
    /// </summary>
    [Tooltip(
        "Whether to update the point cloud. If false, the point cloud will display the content of the temp textures from the last update. " +
        "是否更新点云。 如果为false,则点云将显示上一次更新的临时纹理的内容。")]
    public bool update = true;

    /// <summary>
    /// Flag to check if the update has changed state.
    /// 标记以检查更新是否已更改状态。
    /// </summary>
    private bool previousUpdate = true;

    void Start()
    {
    
    
        if (zedManager == null) //如果还没有实例化
        {
    
    
            zedManager = FindObjectOfType<ZEDManager>(); //找到ZEDManager组件
            if (ZEDManager.GetInstances().Count > 1 //如果这个组件的实例化不只一个,我的情况一般只有一个
                ) //We chose a ZED arbitrarily, but there are multiple cams present. Warn the user.
                 我们任意选择一个ZED,但是有多个相机存在。所以需要警告用户。
            {
    
    
                Debug.Log("Warning: " + gameObject.name +
                          "'s zedManager was not specified, so the first available ZEDManager instance was " +
                          "assigned. However, there are multiple ZEDManager's in the scene. It's recommended to specify which ZEDManager you want to " +
                          "use to display a point cloud.");
            }
        }

        if (zedManager != null) //实例化后的
            zed = zedManager.zedCamera; //相机设备赋值
    }

    // Update is called once per frame
    void Update()
    {
    
    
        //Don't do anything unless the ZED has been initialized.
        // 除非ZED已初始化,否则请勿执行任何操作。

        if (zed.IsCameraReady)
        {
    
    
            if (numberPoints == 0) //这个判断里面的内容只执行一次
            {
    
    
                //Create the textures. These will be updated automatically by the ZED.
                //创建纹理。这些将由ZED自动更新。
                //We'll copy them each frame into XYZTextureCopy and ColorTextureCopy, which will be the ones actually displayed.
                //我们将每帧将它们复制到XYZTextureCopy和ColorTextureCopy中,它们将是显示的。
                XYZTexture = zed.CreateTextureMeasureType(sl.MEASURE.XYZ);
                colorTexture = zed.CreateTextureImageType(sl.VIEW.LEFT);
                numberPoints = zed.ImageWidth * zed.ImageHeight; //点云的数目赋值

                //Load and set the material properties.
                //加载并设置材料属性。
                if (mat == null)
                {
    
    
                    mat = new Material(
                        Resources.Load("Materials/PointCloud/Mat_ZED_PointCloud") as Material); //插件包中加载点云的材质
                }

                if (mat != null)
                {
    
    
                    //mat.SetTexture("_XYZTex", XYZTexture);
                    mat.SetTexture(xyzTexID, XYZTexture); // 把点云的纹理图设置到材质里面
                    //mat.SetTexture("_ColorTex", colorTexture);
                    mat.SetTexture(colorTexID, colorTexture); //把图像的彩色纹理图设置到材质里面
                }
            }

            //If stop updated, create new render texture and fill them with the textures from the ZED.
            //如果停止更新,请创建新的渲染纹理,并使用ZED中的纹理填充它们。
            // These textures will be displayed as they are not updated
            //这些纹理将被显示,因为它们没有更新
            if (!update && previousUpdate != update) //Editor Lance:这个判断好奇怪,好像当previousUpdate为true的时候一定能通过
                // Editor Lance:这边的意思是说  当update为false的时候,这个函数还是被执行了一帧,但是第二帧的时候就不能执行了
            {
    
    
                if (XYZTextureCopy == null) //如果没有复制过之前的点云纹理
                {
    
    
                    XYZTextureCopy = new RenderTexture(XYZTexture.width, XYZTexture.height, 0,
                        RenderTextureFormat.ARGBFloat); //实例化临时纹理,浮点类型
                }

                if (ColorTextureCopy == null) // 如果没有临时的彩色纹理
                {
    
    
                    ColorTextureCopy = new RenderTexture(colorTexture.width, colorTexture.height, 0,
                        RenderTextureFormat.ARGB32); //实例化临时纹理,字符串类型
                }

                //Copy the new textures into the buffers.
                //将新纹理复制到缓冲区中。
                Graphics.Blit(XYZTexture, XYZTextureCopy); //Unity的函数 之后再了解
                Graphics.Blit(colorTexture, ColorTextureCopy);

                if (mat != null) //如果材质已经生成
                {
    
    
                    //mat.SetTexture("_XYZTex", XYZTextureCopy);
                    mat.SetTexture(xyzTexID, XYZTextureCopy); // 应用临时纹理
                    //mat.SetTexture("_ColorTex", ColorTextureCopy);
                    mat.SetTexture(colorTexID, ColorTextureCopy); //   应用临时纹理
                }
            }

            //Send the textures to the material/shader.
            //将纹理发送到材质/着色器。
            if (update && previousUpdate != update && mat != null
            ) // 暂停后又重新开始的话能够进入,但是当update为false的时候是不进入的。当mat没有初始化的时候也是不能进入的。
            {
    
    
                //mat.SetTexture("_XYZTex", XYZTexture);
                mat.SetTexture(xyzTexID, XYZTexture);
                //mat.SetTexture("_ColorTex", colorTexture);
                mat.SetTexture(colorTexID, colorTexture);
            }

            previousUpdate = update;
        }
    }


    void OnApplicationQuit() //退出的时候释放内存
    {
    
    
        //Free up memory.
        mat = null;
        if (XYZTextureCopy != null)
        {
    
    
            XYZTextureCopy.Release(); //释放临时纹理的内存
        }

        if (ColorTextureCopy != null)
        {
    
    
            ColorTextureCopy.Release(); //释放临时纹理的内存
        }
    }

    void OnRenderObject()
    {
    
    
        if (mat != null) //如果材质已经实例化
        {
    
    
            if (hiddenObjectFromCamera == Camera.current) return; //如果我就不想看点云的话

            if (!display) return; //Don't draw anything if the user doesn't want to. 如果用户不想画任何东西。

            //mat.SetMatrix("_Position", transform.localToWorldMatrix);
            mat.SetMatrix(positionID, transform.localToWorldMatrix); //从局部转换到世界坐标系中,
            mat.SetPass(0); //这个是啥

#if UNITY_2019_1_OR_NEWER
            Graphics.DrawProceduralNow(MeshTopology.Points, 1, numberPoints);
#else
            Graphics.DrawProcedural(MeshTopology.Points, 1, numberPoints);
#endif
        }
    }
}

Guess you like

Origin blog.csdn.net/scy261983626/article/details/108350346