2024-04-03 NO.4 Quest3 手势追踪抓取物体

文章目录

  • 1 手势抓取方式
    • 1.1 Hand Grab
    • 1.2 Touch Hand Grab
    • 1.3 Distance Hand Grab
  • 2 HandGrabExamples 示例场景
    • 2.1 Interactor 对象
    • 2.2 Interactable 对象
      • 2.2.1 父子结构
      • 2.2.2 “Hand Grab lnteractable” 脚本
      • 2.2.3 “Move Towards Target Provider” 脚本
      • 2.2.4 其他 Movement Provider
  • 3 抓取配置
    • 3.1 玩家配置
      • 3.1.1 自制预制体
      • 3.1.2 添加交互功能
    • 3.2 物体配置
      • 3.2.1 配置 HandGrabInteractable
      • 3.2.2 One Grab Free Transformer
      • 3.2.3 Two Grab Free Transformer
    • 3.3 颜色高亮显示
  • 4 添加物理抛掷效果
  • 5 录制抓取手势
    • 5.1 场景录制
    • 5.2 工具录制
    • 5.3 手势镜像和缩放
  • 6 远距离抓取物体
    • 6.1 玩家配置
    • 6.2 物体配置
      • 6.2.1 抓取配置
      • 6.2.2 添加物理效果

1 手势抓取方式

1.1 Hand Grab

  1. 无抓取手势(手和物体会穿模)

    适合非实物的抓取,例如魔法球。

image-20240401154501544
  1. 有抓取手势(给不同形状的物体制作不同的抓取手势)
  • Pinch Grab:手指靠近物体,做捏合动作激活。
image-20240401154559680
  • Palm Grab:手掌靠近物体,做握持动作激活。
image-20240401154223604
  • Pinch Grab + Palm Grab:多个抓取点,每个抓取点对应不同抓取姿势。
image-20240401154811065

适用场景

​ 在需要精准抓取手势或者固定某几个抓取手势时,可使用 Hand Grab。

image-20240401160027921

1.2 Touch Hand Grab

image-20240401154311300

​ 可以在物体表面(准确来说是物体的碰撞体)上的任意位置进行抓取,抓取时手指会贴在物体表面上,可以用任意根手指进行抓取。

​ 相比于 Hand Grab,抓取手势更自由。

1.3 Distance Hand Grab

image-20240401154320144

​ 在远距离通过射线抓取物体,可以将远处的物体抓取到手上,或者在远距离操控物体移动。

2 HandGrabExamples 示例场景

​ VR 中手势交互需要两个对象:

  • Interactor:发起交互的对象。
  • Interactable:可以被交互的对象。

2.1 Interactor 对象

​ 展开玩家物体 OVRCamreaRig,其子物体 OVRInteraction 是所有交互功能的父物体:

  • OVRHmd:头显交互。
  • OVRControllerDrivenHands:手柄交互(手柄控制虚拟手部模型的相关功能)。
  • OVRHands:手势追踪交互。
image-20240401164506695

​ 展开 OVRHands > LeftHand > HandInteractorsLeft,可看到左手的 Interactor 共有两个:

  • HandPokeInteractor:手指点触交互(手指点击虚拟按钮)。
  • HandGrabInteractor:手部抓取交互。
image-20240401165127233
  1. HandGrabAPI:检测 Hand Grab 是否选中或者取消选中可抓取物体。即,检测抓取动作是否发生。

  2. HandWristPoint:控制在抓取时虚拟手部和现实手部在位置和旋转角度上的偏移。

    • Offset:位置偏移。
    • Rotation:角度偏移。
    image-20240401165654917
  3. GripPoint:Palm Grab 的探测范围。

    调整 GripPoint 上的 HandWristOffset 脚本参数可以修改探测范围的位置和旋转角度。物体进入探测范围后触发抓取,会被吸到手上。

    image-20240401165845549
  4. PinchPoint:Pinch Grab 的探测范围。

    范围大小取决于 PinchPoint 子物体的 Collider 的碰撞体大小。

    image-20240401170033887
  5. PinchArea:PinchPoint 的 HandPinchOffset 脚本默认引用 PinchArea , PinchArea 碰撞体的位置会影响 PinchPoint 探测范围的位置。

  6. HandGrabVisual :连接 SyntheticHand ,在手部呈现出完整的抓取手势后固定手部姿态,让抓取手势不与物体穿模。

  7. HandGrabGlow:控制抓取时手部的特效。

    image-20240401172533854
    • Glow Color Grabing:抓取时特效的颜色。

    • Glow Color Hover:靠近时特效的颜色。

    • Glow Type:特效类型。

      • Outline:手指轮廓高亮。
      image-20240401172235645
      • Fill:手指颜色填充。
      image-20240401172416873
      • Both :结合 Outline 和 Fill。

2.2 Interactable 对象

2.2.1 父子结构

​ 可抓取物体上需要添加 “Grabbable” 脚本,以实现在抓取物体的时候控制物体的位移、旋转和缩放。

image-20240402160241906

​ 可抓取物体下有一到多个 HandGrabInteractable 物体,即 Hand Grab 所需要的 Interactable 对象。

​ 在示例场景 HandGrabExamples 中,Interactable 对象被统一存放在 Interactables 路径下。以 SimpleGrab2PalmGrab 为例,其子物体 HandGrabInteractable 挂载了交互脚本 “Hand Grab lnteractable”。

image-20240401164416438

2.2.2 “Hand Grab lnteractable” 脚本

image-20240402160758438
  • Supported Grab Type:抓取方式。

    • Palm:捏合抓取。
    • Pinch:握持抓取。
    • All:二者均可。
  • Pinch / Palm Grab Rules:抓取触发手指的规则。

    Thumb、lndex、Middle、Ring、Max:大拇指、食指、中指、无名指、小指。

    • Required:标记了 Required 的手指,必须参与到抓取的触发过程中。即,想要抓起一个物体,必须要用到 Required 手指。
    • Optional:如果没有 Required 手指,则至少要用到一个标记 Optional 的手指。
    • Ignore:标记了 Ignore 的手指,不会被考虑到抓取的触发过程中。

    Unselect Mode:取消抓取的判定条件。

    • All Released:所有 Required 或者 Optional 手指松开后,视为取消抓取。
    • Any Released:有一个 Required 手指松开后,视为取消抓取。
  • Hand Alignment(Unity 中单词拼写错误):决定虚拟手如何变化到对应的抓取手势。

    • None:没有对应限制,会穿模。与没有添加 SyntheticHand 效果一样。
    • AIign On Grab:靠近物体时(即处于 hover 状态)虚拟手会与物体发生穿模。抓取时手部从物体内部快速调整到物体表面。
    • Attract On Hover:靠近物体时虚拟手会被限制在物体外部,不会穿模。抓取时手部直接吸附在物体表面。
    • Align Fingers On Hover:靠近物体时虚拟手会慢慢靠近物体。抓取时手部慢慢吸附到物体表面,穿模程度较小。
  • [Optional] ScaIed Hand Grab Poses:为不同大小的手配置相应的抓取手势。

    • HandGrab Point:后续专门介绍。

2.2.3 “Move Towards Target Provider” 脚本

​ 在运行程序时,如果当前 HandGrabInteractable 物体上没有挂载 “Move Towards Target Provider” 脚本,“Hand Grab lnteractable” 脚本会自动添加 “Move Towards Target Provider” 脚本,用于控制物体被抓取时朝向手部的移动。

image-20240402170405450
  • Travel Speed:移动速度。值越大,移动时间越长。

​ 如果想在程序运行前控制物体朝向手部的移动速度,可以在 HandGrabInteractable 物体上添加 “Move Towards Target Provider” 脚本,并设置其引用。

image-20240402171109624

2.2.4 其他 Movement Provider

(1)Move From Target Provider

​ 抓取时将手部吸附到物体上,而不是物体吸附到手上。

image-20240402171525204

(2)Follow Target Provider

​ 抓取时物体会跟随手部移动,具有阻尼效果。

image-20240402171636276
  • Speed:物体跟随速度。

3 抓取配置

3.1 玩家配置

3.1.1 自制预制体

(1)将 《2024-04-01 NO.3 Quest3 手势追踪与玩家角色配置》 文章中 SampleScene 场景下的 OVRCameraRig 进行 Prefab Unpack Completely,之后拖拽到 Assets > Prefabs 文件夹下。

image-20240402200905432

3.1.2 添加交互功能

(1)在 Package 中找到 HandGrabInteractor 预制体,将其拖拽为 SampleScene 场景中 MyOVRCameraRig > OVRInteraction > OVRHands > LeftHand > HandInteractorsLeft 的子物体。并对 RightHand 进行同样的操作。

image-20240402201242950

(2)场景中展开 LeftHand 下的 HandGrabInteractor 对象,将其 Visuals 下的两个子对象 HandGrabVisual 和 HandGrabGlow 激活,并设置对应的引用参数。同样的操作应用于 RightHand(步骤中所有 Left 对象改为 Right)。

  • HandGrabVisual:
    • Synthetic Hand <-- OVRLeftHandSynthetic。
  • HandGrabGlow:
    • Hand Visual <-- OVRLeftHandSynthetic > OVRLeftHandVisual。
    • Hand Renderer <-- OVRLeftHandSynthetic > OVRLeftHandVisual > OculusHand_L > l_handMeshNode。
    • Material Editor <-- OVRLeftHandSynthetic > OVRLeftHandVisual > OculusHand_L > l_handMeshNode。
image-20240402202042735 image-20240402202143256

(3)找到 LeftHand > HandInteractorsLeft 物体上的 “Best Hover lnteractor Group” 脚本,将 HandInteractorsLeft 物体拖拽入 Interactors 列表中。同样的操作应用于 RightHand > HandInteractorsRight 物体(步骤中所有 Left 对象改为 Right)。

image-20240402202813087

​ Interactors 列表存储不同种类的 Interactor 脚本。

​ Interactor Group 保证其列表下的所有 Interactor 在同一时刻只有一个进行交互,而其他 Interactor 暂时失活。

​ 此处 Best Hover Interactor Group 是 Meta XR SDK 中 Interactor Group 的其中一种。其特性是:

  1. 保证优先级高的 Interactor 进入到 hover 状态,优先级低的 Interactor 会暂时失活。

  2. 默认情况下,越靠前的列表元素拥有越高的优先级。

3.2 物体配置

3.2.1 配置 HandGrabInteractable

(1)在场景中创建一个桌面(Cube,这里配置了红色材质),桌面上放一个立方体 Cube 用于抓取。

​ 同时,给 Cube 添加 Rigidbody 和 Grabbable 组件,并将其 Box Collider 设置为 Trigger,取消勾选 Rigidbody 的 Use Gravity 选项。

​ 最后,勾选 Grabbable 的 Transfer On Second Selection 选项,以实现左右手交替抓取。

image-20240402205603844

(2)在 Project 中找到 HandGrabInteractable 预制体,将其拖拽为 Cube 的子物体。可以看见 HandGrabInteractable 自动寻找到了其父物体中的 Grabbable 和 Rigidbody。

image-20240402205157590

3.2.2 One Grab Free Transformer

​ 到此,运行程序,可以实现双手抓取移动 Cube。

​ 运行程序时,可以看到 Cube 物体上自动添加了 One Grab Free Transformer 脚本,并且被 Grabbable 脚本引用。

image-20240402210103367

​ Grabbable 脚本通过 Transformer 来控制物体被抓取时的移动旋转和缩放。默认使用 One Grab Free Transformer 脚本(一只手控制)。

​ 其他 One Grab Transformer:

image-20240402210628398
  • One Grab Rotate Transformer:仅控制物体旋转。
  • One Grab Scale Transformer:仅控制物体缩放。
  • One Grab Translate Transformer:仅控制物体平移。
  • One Grab Physics Joint Transformer:相对而言使用的很少。

3.2.3 Two Grab Free Transformer

​ 取消勾选 Cube 挂载的 Grabbable 脚本的 Transfer On Second Selection 选项,并更换 One Grab Free Transformer 脚本为 Two Grab Free Transformer 脚本,即可使用双手操控物体。

image-20240402211242487

​ 若想实现单双手都可操控,则同时添加 One Grab Free Transformer 脚本即可。

image-20240402211415484

3.3 颜色高亮显示

(1)在 Cube 下方新建空子物体 Visuals,用于控制 Cube 的颜色显示。

(2)为 Cube 依次添加以下脚本:

  1. Interactable Color Visual:控制物体在各种状态下显示的颜色。

    需要设置:

    • Interactable View <-- Material Property Block Editor 脚本。
    • Editor <-- Interactable Group View 脚本。
  2. Material Property Block Editor:关联物体材质。

    需要设置:

    • Renderers <-- Cube 的 Mesh Renderer 组件。
  3. Interactable Group View:可交互物体组。

    需要设置:

    • Interactables <-- HandGrabInteractable。
image-20240402213125272

​ 设置完成后,即可通过改变 Interactable Color Visual 中的 Color State 来更改物体对应状态的颜色。

​ 到此,我们可以对 Cube 进行抓取、移动和旋转,但是没有录制抓取手势。

4 添加物理抛掷效果

(1)取消 Cube 的 Box Collider 的 Trigger 选项,并勾选 Rigidbody 的 Use Gravity。此时,手部可以和 Cube 进行碰撞,手部碰撞体在 MyOVRCameraRig > TrackingSpace > LeftHandAnchor > OVRHandPrefab 下(运行状态下可见)。

image-20240402214921602

​ 这里运行时产生碰撞体是因为先前设置了 Enable Physics Capsules 选项。

image-20240402215126160

(2)为 Cube 添加 Physics Grabbable 脚本,添加时会自动关联 Cube 上的 Rigidbody 和 Grabbable。

image-20240402215439917

(3)将 Cube 上的 Physics Grabbable 脚本关联到 HandGrabInteractable 对象上。

image-20240402215620437

(4)在 Project 中找到 HandVelocityCaIculator,将其拖拽为 LeftHand / RightHand 的子物体。

image-20240402215835097

(5)关联对应的 LeftHand / RightHand。

image-20240402221145893

(6)将 HandVelocityCaIculator 关联到 HandInteractorsLeft > HandGrabInteractor 和 HandInteractorsRight > HandGrabInteractor 对象上。

image-20240402220137277

​ 此时,即可完成 Cube 物理抛掷的效果。

image-20240403102522126

​ 如果在抛掷过程中有穿模现象,可以将 Cube 的 Rigidbody 的 Collision Detection 设置为 Continuous Dynamic,进行连续动态的碰撞检测,但性能消耗会更大。

image-20240402220309344

5 录制抓取手势

5.1 场景录制

​ 录制抓取手势需要在 Unity 编辑器运行模式下进行,并且需要将头显和电脑进行串流(串流部分在 《2024-03-28 NO.1 Quest3 开发环境配置教程-CSDN博客》 中提及)。

image-20240403103331979

(1)打开 HandGrabPoseTool 场景,添加待录制的物体 Cube(这里还添加了一个子物体 Cube)。并确保物体上挂载 Rigidbody 组件和 Grabbable 脚本,没有则手动添加。

image-20240403103216459

​ 这里将 BoxCollider 设置为 Trigger,取消勾选了 Rigidbody 的 Use Gravity 选项,并勾选了 Grabbable 脚本的 Transfer On Second Selection。

image-20240403110006980

(2)运行 Unity,按下按钮,开始做抓取手势动作,3s 后将自动结束录制。若想要延长录制准备时间,可在前方点击按钮进行调整。注意,录制完成后不要急着退出运行模式。

(3)录制完成后,可以看见 Cube 下方多了 HandGrabInteractable 子物体。首先将 Cube 拖拽至 Assets > Prefabs 文件夹下成为预制体,再退出 Unity 运行模式。

image-20240403111138734

(4)在 Unity 编辑模式下,删除场景中原有的 Cube,将刚创建的预制体拖入场景,开始进行手势微调。

​ 点击 HandGrabInteractable > HandGrabPose 物体,找到其挂载的 Hand Grab Pose 脚本,调节其参数以达到想要的手势。

image-20240403111708236
  • Fingers Freedom:手指灵活程度。

    • Locked:抓取时,虚拟手指无法跟随现实手指进行弯曲。
    • Constrained:抓取时,虚拟手指可以向外弯曲而不能向内。
    • Free:抓取时,虚拟手指不受限制。
  • Joint Angles:关节角度。

    改变值可旋转每个关节的角度,也可以在 Scene 窗口中直接旋转蓝色圆圈编辑调节。

    image-20240403112030781

​ 微调完成后,失活 HandGrabPose 的子物体 Ghost-RightHand(Clone),即可取消显示录制手势。之后抓取物体时,手部会呈现刚录制好的姿势。

image-20240403112653600

5.2 工具录制

​ 点击上方菜单 Oculus > Interaction > Hand Grab Pose Recorder,打开录制窗口。

image-20240403113546970

(1)配置场景中想要录制的手,以及待录制物体的刚体组件。这里选择的是右手。

image-20240403113903025

(2)运行 Unity,在做好手势后用鼠标点击 Record HandGrabPose 按钮即可完成录制。建议录制时将物体的 Collider 选择 Trigger,并取消勾选了 Rigidbody 的 Use Gravity。

​ 由于录制时带着头显,不方便使用鼠标。因此可以配置相应的键盘按键(默认是空格),按下该键盘按键后即可完成录制。使用键盘按键来结束录制时,需要先将鼠标双击

Hand Grab Pose Recorder 录制窗口,以获取焦点。

​ 注意,录制完成后不要急着退出运行模式。

image-20240403114948243

(3)录制完成后,点击 Save To Collection 按钮保存录制结果,再退出 Unity 运行模式。

image-20240403115057133

(4)在 Unity 编辑模式下点击 Load From Collection 按钮,即可获取刚录制的手势。

image-20240403115346225

​ 可以看到,Cube 下方添加了两个 HandGrabInteractable,且其中一个记录了手势。其上方没有手势的 HandGrabInteractable 是因为录制前 Cube 拥有一个 HandGrabInteractable 子物体,在读取结果时将其一并拷贝了进来,这里删除即可。

image-20240403115417622

​ 之后录制时,不需要先给物体配置 HandGrabInteractable,添加好 Rigidbody 后直接录制即可。

5.3 手势镜像和缩放

​ 选中需要镜像手势的父物体 HandGrabInteractable,点击 Create Mirrored HandGrabInteractable 按钮,即可生成镜像手势。

image-20240403190448779

​ 调节 Scaled Hand Grab Poses 下方的 Scale 值,点击 Add HandGrabPose Key with Scale XXX 按钮后,即可生成对应缩放比例的手势。

image-20240403190858627

6 远距离抓取物体

6.1 玩家配置

(1)在 Project 窗口中找到 DistanceHandGrabInteractor 预制体,将其拖拽为 HandInteractorsLeft / HandInteractorsRight 的子物体。同时,将其挂载到 HandInteractorsLeft / HandInteractorsRight 的 Interactors 列表下。

image-20240403192146073

(2)展开 DistanceHandGrabInteractor 的 Visuals 子物体,将其两个子物体激活。并进行如下关联(与 3.1.2 节 相同):

  • HandGrabVisual:
    • Synthetic Hand <-- OVRLeftHandSynthetic。
  • HandGrabGlow:
    • Hand Visual <-- OVRLeftHandSynthetic > OVRLeftHandVisual。
    • Hand Renderer <-- OVRLeftHandSynthetic > OVRLeftHandVisual > OculusHand_L > l_handMeshNode。
    • Material Editor <-- OVRLeftHandSynthetic > OVRLeftHandVisual > OculusHand_L > l_handMeshNode。

​ 同样的操作对 OVRRightHandSynthetic 再执行一遍(步骤中所有 Left 对象改为 Right)。

image-20240403192704980 image-20240403192827902

(3)将先前配置好的 HandVelocityCalculator 关联到 DistanceHandGrabInteractor 上。该步骤为可选,但需注意左右手对应配置。

image-20240403193055687

6.2 物体配置

6.2.1 抓取配置

​ 参考 3.2.1 节 内容,创建一个 Cube,添加 Rigidbody 和 Grabbable 脚本,并将其设置为 Trigger,取消 Use Gravity。

​ 之后,为该物体添加 Distance Hand Grab Interactable 脚本,添加时会自动关联 Cube 上的 Rigidbody 和 Grabbable。

image-20240403193731345

​ 此时运行 Unity,双手对准 Cube 握拳后,Cube 会被远距离抓到手上。这是因为 Cube 上 Interactable 脚本的 Supported Grab Types 和 RightHand 下 Interactor 的 Supported Grab Types 都是 Pinch。 如果不匹配,则不会被抓取。

image-20240403194241056 image-20240403194225022

6.2.2 添加物理效果

(1)准备模型,这里使用两个 Cube 当成一把剑。其父子结构如下图。

​ 给 Sword 添加 Rigidbody 和 Grabbable 组件,同时添加 Physics Grabbable 脚本。

image-20240403203205500

​ Cube 和 Cube (1) 上带有 BoxCollider,且均设置为 Trigger。

(2)进行手势录制,并做一些微调。这里将所有手指都设置为 Locked。

image-20240403203640338

(3)在生成的 HandGrabInteractable 物体上添加 Distance Hand Grab Interactable 脚本,并为其关联 Physics Grabbable 脚本。

​ 对于 Hand Grab Interactable 脚本,其 Physics Grabbable 的引用在录制时被自动关联,因此这里不需要再重复关联。也可以手动检查确认一下。

image-20240403203953314

(4)恢复物体的 Use Gravity,并且将 Collider 的 Trigger 选项取消。此时这把“剑”便拥有了远距离抓取和抛掷的功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/790506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

5.5G,只比6G少0.5G

5.5G成为通信行业2024年开年的一大焦点。提到5.5G&#xff0c;多出来的0.5G又是啥&#xff1f;为什么不直接迈向6G时代&#xff1f;今天我们一探究竟&#xff01; “0.5G”&#xff0c;现在与未来的桥梁 2021年&#xff0c;国际标准组织3GPP为通信技术的进一步发展定义了新的里…

AI绘图:Stable Diffusion WEB UI 详细操作介绍:进阶-面部修复和调参

结合两篇文章完成了本地部署和基础操作,现在我们来介绍下进阶内容:面部修复,高清修复和调参区。 一:脸部修复 面部修复的适用在画真人、三次元的场景,特别是在画全身的时候 一般在画全身,由于脸部占比的空间比较小,那么绘制出来的效果就会比较差 1.面部修复 SD 支持…

利用sqoop实现sql表数据导入到Hadoop

1.在开发这创建好sql表后&#xff0c;开始执行下面步骤 2.sqoop的安装路径&#xff0c;我这里放在以下位置 3. 进入到option2脚本中&#xff0c;下面是脚本里的内容 下面四点要根据情况随时更改&#xff1a; 1>jdbc:mysql://node00:3306/数据库名 2>sid,sname->前…

BGP-(as-path-filter)

BGP-as-path-filter&#xff0c;缺省 as-path-filter&#xff0c;正则表达式&#xff0c;as-path过滤器&#xff0c;对于BGP的as-path属性实际上可以看成是一个包含空格的字符串。 特点&#xff1a;1、通过对BGP路由的as-path属性进行匹配达到对BGP路由的过滤。 2、在route-…

鸿蒙分布式音乐播放-如何完成播放、暂停、上一曲、下一曲功能

介绍 本示例使用fileIo获取指定音频文件&#xff0c;并通过AudioPlayer完成了音乐的播放完成了基本的音乐播放、暂停、上一曲、下一曲功能&#xff1b;并使用DeviceManager完成了分布式设备列表的显示和分布式能力完成了音乐播放状态的跨设备分享。 本示例用到了与用户进行交…

【VUE+ElementUI】el-table表格固定列el-table__fixed导致滚动条无法拖动

【VUEElementUI】el-table表格固定列el-table__fixed导致滚动条无法拖动 背景 当设置了几个固定列之后&#xff0c;表格无数据时&#xff0c;点击左侧滚动条却被遮挡&#xff0c;原因是el-table__fixed过高导致的 解决 在index.scss中直接加入以下代码即可 /* 设置默认高…

音频转换工具 Bigasoft FLAC Converter for Mac

Bigasoft FLAC Converter for Mac是一款专为Mac用户设计的音频转换工具&#xff0c;它能够将FLAC音频文件高效、高质量地转换为其他常见的音频格式&#xff0c;如MP3、AAC等。这款软件具有直观易用的界面&#xff0c;使用户能够轻松上手&#xff0c;无需复杂的操作步骤即可完成…

Redis底层数据结构-Dict

1. Dict基本结构 Redis的键与值的映射关系是通过Dict来实现的。 Dict是由三部分组成&#xff0c;分别是哈希表&#xff08;DictHashTable&#xff09;&#xff0c;哈希节点&#xff08;DictEntry&#xff09;&#xff0c;字典&#xff08;Dict&#xff09; 哈希表结构如下图所…

阿里云服务器购买租用价格多少钱一年?61元、99元、165元、199元

阿里云服务器租用价格表2024年最新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核…

Delphi 是一种内存安全的语言吗?

上个月&#xff0c;美国政府发布了 "回到基石 "报告&#xff1a; 通往安全和可衡量软件之路 "的报告。该报告是美国网络安全战略的一部分&#xff0c;重点关注多个领域&#xff0c;包括内存安全漏洞和质量指标。 许多在线杂志都对这份报告进行了评论&#xff0…

C语言内存函数,让内存管理更高效!

1. memcpy使⽤和模拟实现 2. memmove使⽤和模拟实现 3. memset函数的使⽤ 4. memcmp函数的使⽤ 正文开始&#xff1a; 1. memcpy 使⽤和模拟实现 void * memcpy ( void * destination, const void * source, size_t num ); • 函数memcpy从source的位置开始向后复…

区间概率预测python|QR-CNN-BiLSTM+KDE分位数-卷积-双向长短期记忆神经网络-时间序列区间概率预测+核密度估计

区间预测python|QR-CNN-BiLSTMKDE分位数-卷积-双向长短期记忆神经网络-核密度估计-回归时间序列区间预测 模型输出展示&#xff1a; (图中是只设置了20次迭代的预测结果&#xff0c;宽度较宽&#xff0c;可自行修改迭代参数&#xff0c;获取更窄的预测区间&#xff09; 注&am…

类似微信的以文搜图功能实现

通过PaddleOCR识别图片中的文字&#xff0c;将识别结果报存到es中&#xff0c;利用es查询语句返回结果图片。 技术逻辑 PaddleOCR部署、es部署创建mapping将PaddleOCR识别结果保存至es通过查询&#xff0c;返回结果 前期准备 PaddleOCR、es部署请参考https://blog.csdn.net…

stm32之基本定时器的使用

在上文我们使用到了HAL库的自带的延时函数&#xff0c;HAL_Delay&#xff08;&#xff09;&#xff1b;我们来看一下函数的原型 __weak void HAL_Delay(uint32_t Delay) {uint32_t tickstart HAL_GetTick();uint32_t wait Delay;/* Add a freq to guarantee minimum wait */…

【SQL】1587. 银行账户概要 II

题目描述 leetcode题目&#xff1a;1587. 银行账户概要 II Code 写法一 select name, sum(amount) as balance from Users U left join Transactions T on U.account T.account group by U.account having sum(amount) > 10000写法二 select Users.name, balance from…

Unity自定义icon

Unity自定义icon 1. 新建文件夹 OfficeFabricIconSet2. 新建Iconset3. 新建子文件夹Textures并添加icon图片4. 向iconset添加Quad Icons5. 最终效果 教程来源处&#xff1a; https://365xr.blog/build-your-own-button-icon-set-for-microsoft-hololens-2-apps-with-mrtk-using…

前视声呐目标识别定位(三)-部署至机器人

前视声呐目标识别定位&#xff08;一&#xff09;-基础知识 前视声呐目标识别定位&#xff08;二&#xff09;-目标识别定位模块 开发了多波束前视声呐目标识别定位模块后&#xff0c;自然期待能将声呐部署至AUV&#xff0c;实现AUV对目标的抵近观测。原本规划着定位模块不…

C++算法——二分法查找

一、二分查找算法思想和模版 1.算法思想 2.细节处理 3.模板 二、二分查找 1.链接 704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; 2.描述 3.思路 先从最经典的题目去切入&#xff0c;思路就是二分查找&#xff0c;这里我们认为&#xff0c;目标值既可以看作为左部…

XSS 与 CSRF 攻击——有什么区别,如何加以防护

跨站脚本(XSS)和跨站请求伪造(CSRF)&#xff0c;它们将恶意脚本注入目标系统&#xff0c;以进一步利用技术栈或窃取用户数据。 什么是 XSS 和 CSRF? CSRF和XSS都是客户端攻击&#xff0c;它们滥用同源策略&#xff0c;利用web应用程序和受害用户之间的信任关系。XSS和跨站脚…

WPS二次开发系列:以自动播放模式打开PPT文档

在前面文章中 WPS SDK打开文档并实现保存回传 介绍了如何使用WPS SDK打开文档&#xff0c;那么我们是否能够实现在打开WPS 文档的时候能够传递一些参数来控制打开文档的行为呢&#xff0c;经过研究WPS SDK相关文档和API&#xff0c;最终实现了 以自动播放方式打开PPT文档功能。…