Open Cascade 7.7.1 动画 AIS_Animation

2023-12-30 20:30

本文主要是介绍Open Cascade 7.7.1 动画 AIS_Animation,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1. 简介
  • 2. 使用方法
    • 2.1. 对象变换动画
    • 2.2. 相机变换动画
    • 2.3. 多对象+相机同时变换动画
  • 3. OCC 7.7.1 升级说明
  • 4. 疑问
  • 参考资料

​转载请注明原文链接:https://blog.csdn.net/Mechanicoder/article/details/130539644

1. 简介

3D动画效果在一些软件中很常见,动画有助于使用者观察模型或视角的变化轨迹,避免画面突变,提升交互体验。

在OCC中3D视图中显示物体位置动画变换和相机视角动画变换是由 AIS_Animation 实现的。对象变换动画为 AIS_AnimationObject、相机变换动画为 AIS_AnimationCamera
AIS_Animation
模型变换动画+相机变换动画

2. 使用方法

由于没有单独的渲染子线程,动画时采用阻塞主线程的方式刷新的:

Handle(AIS_Animation) anim = ...;
anim_object->SetOwnDuration(obj_duration); // 设置时间
ais_animation->StartTimer(0, 1.0, true); // 开始定时器
while (!anim->IsStopped())
{anim->UpdateTimer();_context->UpdateCurrentViewer();
}

一个动画AIS_Animation可以理解为一个时间轴,在一个时间轴上通过方法Add添加多个动画,实现同时播放多个动画的效果。因为AIS_Animation的继承关系,对象动画和相机动画是可以同时播放的,如2.3节所示。

//! Add single animation to the timeline.
//! @param theAnimation input animation
Standard_EXPORT void Add (const Handle(AIS_Animation)& theAnimation);

多个动画时间轴的效果与视频编辑中的时间轴类似。
视频编辑时间轴

2.1. 对象变换动画

AIS_AnimationObject 初始化接口为:

  //! Constructor with initialization.//! Note that start/end transformations specify exactly local transformation of the object,//! not the transformation to be applied to existing local transformation.//! @param[in] theAnimationName animation identifier//! @param[in] theContext       interactive context where object have been displayed//! @param[in] theObject        object to apply local transformation//! @param[in] theTrsfStart     local transformation at the start of animation (e.g. theObject->LocalTransformation())//! @param[in] theTrsfEnd       local transformation at the end   of animationStandard_EXPORT AIS_AnimationObject (const TCollection_AsciiString& theAnimationName,const Handle(AIS_InteractiveContext)& theContext,const Handle(AIS_InteractiveObject)&  theObject,const gp_Trsf& theTrsfStart,const gp_Trsf& theTrsfEnd);

这里需要注意,输入参数的 theTrsfStarttheTrsfEnd 是指对象 theObject 的 “局部变换”——是对象位置的绝对值、而非相对值,例如 theTrsfStart 可以直接取对象当前的位置变换 theObject->LocalTransformation()。而当起始变换不是对象当前位置的变换 theObject->LocalTransformation() 时,对象会出现跳动的现象,即由指定的起始位置theTrsfStart变换到终止位置theTrsfEnd,而与当前位置无关。例如,对象起始位置为单位变换,终止位置为绕轴ax1旋转90°,实现代码:

gp_Trsf start_trsf, end_trsf;
gp_Ax1 ax1(gp_Pnt(10, 0, 0), gp_Vec(0, 1, 0));
end_trsf.SetRotation(ax1, M_PI_2);
Handle(AIS_AnimationObject) ani_object = new AIS_AnimationObject("Object", _context, first_obj, start_pnt, end_pnt);

重复执行上一段代码,会出现跳动的现象:
指定在这里插入图片描述

这里引入了一个概念:对象位置。可以简单理解为物体在渲染时,对物体本身的三角形数据施加一个变换,从而将物体显示在所需的位置。例如,希望将一个球心在原点的单位球,渲染显示在(10, 10, 10)这个位置,只需设置物体显示对象的位置变换即可:

Handle(AIS_InteractiveObject) ais_ball;
gp_Trsf ball_trsf;
ball_trsf.SetTranslation(gp_Vec(10, 10, 10));
ais_ball->SetLocalTransformation(ball_trsf);

详细可参考OCC官方文档:AIS_InteractiveObject

2.2. 相机变换动画

AIS_AnimationCamera

//! Define camera start position.
void SetCameraStart (const Handle(Graphic3d_Camera)& theCameraStart) { myCamStart = theCameraStart; }
//! Define camera end position.
void SetCameraEnd (const Handle(Graphic3d_Camera)& theCameraEnd) { myCamEnd = theCameraEnd; }

视角切换动画是在两个相机视角之间完成的,分别设置起始相机位置、终止相机位置。实现代码:

gp_Trsf end_trsf;
gp_Ax1 ax1(gp_Pnt(10, 0, 0), gp_Vec(0, 1, 0));
end_trsf.SetRotation(ax1, M_PI_2);
Handle(Graphic3d_Camera) camera_start = _view->GetView()->Camera();
Handle(Graphic3d_Camera) camera_end = new Graphic3d_Camera();
camera_end->Copy(camera_start);
camera_end->Transform(end_trsf);
Handle(AIS_AnimationCamera) ani_camera = new AIS_AnimationCamera("Camera", _view->GetView());
ani_camera->SetCameraStart(camera_start);
ani_camera->SetCameraEnd(camera_end);

将相机绕轴ax1正向旋转90°。注意:在同一个3D视图中相机变换和模型变换在视觉上是相反的。
相机视角切换动画

2.3. 多对象+相机同时变换动画

多对变换动画

3. OCC 7.7.1 升级说明

OCC 7.7.1 版本中优化了对旋转变换的支持,新增专门针对旋转变换的对象动画AIS_AnimationAxisRotation,以解决此前版本中对象旋转动画中间过程不正确的问题(bug32570 绕轴旋转动画中间过程不正确),参考 OCC 开发者 Kirill Gavrilov 对该问题的回复。

以对象变换动画AIS_AnimationObject为例,更新动画帧时以变换插值gp_TrsfNLerp的方式获取中间变换,即分别对平移、旋转、缩放进行插值,并组合成新的变换,无法得到正确的变换路径。

void NCollection_Lerp<gp_Trsf>::Interpolate (double theT, gp_Trsf& theResult) const
{...gp_XYZ aLoc;gp_Quaternion aRot;Standard_Real aScale = 1.0;myLocLerp  .Interpolate (theT, aLoc);myRotLerp  .Interpolate (theT, aRot);myScaleLerp.Interpolate (theT, aScale);theResult = gp_Trsf();theResult.SetRotation (aRot);theResult.SetTranslationPart (aLoc);theResult.SetScaleFactor (aScale);
}

因此在之前版本或新版本使用AIS_AnimationObject,对象变换动画的效果为:
错误的中间过程

但是,对于绕轴旋转的相机动画,在最新版 OCC 7.7.1 中仍无法得到正确的中间过程。显然,这同样是因为动画AIS_Animation中对gp_Trsf的平移分量、旋转分量分别采用线性插值引起的。

4. 疑问

  1. 如何才能使动画对任意变换均沿着正确的变换路径播放呢?
  2. 动画实际播放时间小于主线程阻塞时间?动画快速播放完成后,仍阻塞至设定时间结束。


本文源码

转载请注明原文链接:https://blog.csdn.net/Mechanicoder/article/details/130539644

参考资料

1. OCC博客 How to rotation arround an axis parallel to the Y-axis
2. Open Cascade 7.7.0 AIS_Animation

这篇关于Open Cascade 7.7.1 动画 AIS_Animation的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/553910

相关文章

Ollama整合open-webui的步骤及访问

《Ollama整合open-webui的步骤及访问》:本文主要介绍如何通过源码方式安装OpenWebUI,并详细说明了安装步骤、环境要求以及第一次使用时的账号注册和模型选择过程,需要的朋友可以参考... 目录安装环境要求步骤访问选择PjrIUE模型开始对话总结 安装官方安装地址:https://docs.

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要

基于Python实现PDF动画翻页效果的阅读器

《基于Python实现PDF动画翻页效果的阅读器》在这篇博客中,我们将深入分析一个基于wxPython实现的PDF阅读器程序,该程序支持加载PDF文件并显示页面内容,同时支持页面切换动画效果,文中有详... 目录全部代码代码结构初始化 UI 界面加载 PDF 文件显示 PDF 页面页面切换动画运行效果总结主

Qt QWidget实现图片旋转动画

《QtQWidget实现图片旋转动画》这篇文章主要为大家详细介绍了如何使用了Qt和QWidget实现图片旋转动画效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、效果展示二、源码分享本例程通过QGraphicsView实现svg格式图片旋转。.hpjavascript

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

Open a folder or workspace... (File -> Open Folder)

问题:vscode Open with Live Server 时 显示Open a folder or workspace... (File -> Open Folder)报错 解决:不可以单独打开文件1.html ; 需要在文件夹里打开 像这样

android java.io.IOException: open failed: ENOENT (No such file or directory)-api23+权限受权

问题描述 在安卓上,清单明明已经受权了读写文件权限,但偏偏就是创建不了目录和文件 调用mkdirs()总是返回false. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_E

动画AnimationDrawable、转动

现实开发中:很多地方都用到 点击动画的特效; 本案例本人做了三个关于“动” 画 的效果; 先上图: 总体图: A: B: 1:点击图片按钮,效果是:图片闪动; 通过在xml中定义:标签:animation-list来实现点击动画的效果;  是否循环标签:oneshot ;   时间间隔标签:duration ; 要显示的图片标签:drawable ;