We Android devs are quite familiar with using object animators on native android views to make subtle micro-interactions and animations. Let's try and extend it to 3D.
我们的 Android开发人员非常熟悉在原生android视图上使用对象动画制作微妙的微交互和动画的能力。 让我们尝试将其扩展到3D。
The challenge
挑战
We at Furlenco had a challenge in explaining the uniqueness of one of our flagship products, Bounce. The peculiarity of Bounce is that it can be arranged in different forms/orientations. It was hard for us to present it to the customer just by using static images.
Furlenco的我们在解释我们的旗舰产品之一Bounce的独特性方面遇到了挑战。 弹跳的独特之处在于它可以按不同的形式/方向排列。 仅使用静态图像,我们很难将其呈现给客户。
The Tech Call
技术电话
We decided to solve this problem using Sceneform SDK which ultimately relays on ARCore (Read more here). There are 2 ways of doing this,
我们决定使用Sceneform SDK解决此问题,该场景最终会在ARCore上进行中继( 在此处了解更多信息 )。 有两种方法可以做到这一点,
Option I — Importing an Animated fbx file (Got from 3D Modelling artist) and let it take care of transitioning between orientations. This had a serious problem — Mutation between states/orientations can’t be controlled by the user. It just loops through all possible orientations without any control — like playing a video in a loop.
选项I-导入动画fbx文件 (Got from 3D Modeling artist),并使其在方向之间过渡。 这是一个严重的问题-用户无法控制状态/方向之间的变化。 它只是在没有任何控制的情况下循环播放所有可能的方向,例如循环播放视频。
Option II— Using Android Native Animators to achieve this. The entire animation loop can be handled using user-triggered events such as swipe, drag, etc. Perfect.!
选项II-使用Android Native Animators实现此目的。 整个动画循环可以使用用户触发的事件(如滑动,拖动等)来处理。完美。
Therefore, Option II Check.!
因此, 选项II检查。
The Resources
资源
We had sceneform generated files such as .sfb
and .sfa
only for 2 assets .ie.,
我们只有两个资产.e。的场景格式生成文件,例如.sfb
和.sfa
,
Main Cushion
主垫
Side Cushion.
侧垫 。
The required structures were cooked by duplicating these primary resources and augmenting into the structures we want.
通过复制这些主要资源并扩充到我们想要的结构中,可以烹调出所需的结构。
The Code Prerequisite
代码先决条件
Here are some stuff you need to know before moving to Code:
在转向代码之前,您需要了解以下几点:
Vector3 — Takes in x, y, z coordinates that represents a point in the virtual space.
Vector3 —接受代表虚拟空间中某个点的x,y,z坐标。
Vector3(float x, float y, float z)
Quaternion — Handles Rotation between two Cartesian coordinates provided in the form of Vector3.
四元数 —处理以Vector3形式提供的两个笛卡尔坐标之间的旋转。
Quaternion.axisAngle(Vector3(float x, float y, float z), degree)
ObjectAnimator — Native Android Object Animators. Read more here.
ObjectAnimator —原生Android对象动画师。 在这里阅读更多。
Interpolator — Native Android Interpolators. Read more here.
插值器 -本机Android插值器。 在这里阅读更多。
Evaluators — Evaluates if the performed Transformation Math is valid. These Evaluators are specific to scene form. — Types: QuaternionEvaluator, Vector3Evaluator.
评价者 -检测,如果进行转化数学是有效的。 这些评估者特定于场景形式。 —类型: QuaternionEvaluator , Vector3Evaluator 。
The Code
代码
The code mainly involves a bit of 3D Math. Let’s break it down. Unlike 2D canvas that we are used to on Android, 3D follows relative coordinate spacing .ie., there is no world coordinates. The first object that you place is primitive and the remaining are placed relative to that. Here are some attempts that went wrong when we started experimenting:
该代码主要涉及一些3D Math。 让我们分解一下。 与我们在Android上习惯的2D画布不同,3D遵循相对坐标间距,即没有世界坐标。 您放置的第一个对象是原始对象,其余对象相对于原始对象放置。 当我们开始实验时,以下尝试会出错:
As you can infer, In Case(i): Making the Top-Left cushion as the primitive renderable and placing remaining renderable relative to it. This was a bad idea because, all the interactions done to transform the asset such as rotation, scaling and translation were with respect to the Top-Left cushion and not with respect to the entire augmented asset that consists of 4 cushions. Case(ii): Make a Transformable Node that isn’t associated with any renderable that stays in the center of the constructed asset and placing all renderable relative to it. Now all transformations happen with respect to the center of the asset. Perfect.!
如您所知,在Case(i)中 :将“左上”缓冲垫设为可渲染的原始图元,并相对于其放置其余可渲染图。 这是一个坏主意,因为完成资产转换的所有交互(例如旋转,缩放和平移)都是针对“左上”缓冲垫,而不是针对由四个缓冲垫组成的整个增强资产。 Case(ii) :创建一个与任何可渲染节点都不相关的可变形节点,该可渲染节点位于构造资产的中心,并相对于其放置所有可渲染节点。 现在,所有转换都相对于资产中心发生。 完善。!
val mainNode = TransformableNode(arFragment?.transformationSystem)
Explaining the code in entirety is quite complex, so let me explain focusing on one anim-set, you can extend this ideology to other anim-sets as well.
完整地解释代码非常复杂,所以让我解释一下集中在一个动画集上,您也可以将此思想扩展到其他动画集。
Create Renderables:
创建可渲染对象:
This converts generated .sfb file in raw into Model Renderable that can be associated with a Transformable Node.
这会将原始生成的.sfb文件转换为可与可转换节点关联的Model Renderable。
Translation Animation:
翻译动画:
Here,
这里,
ObjectAnimator is set with 2 Vector3 s — representing the start and end position. Notice mainLocalPosZ + 1.0f — translation happens along Z-axis for
sideCushion
, which is intended.ObjectAnimator设置了2个Vector3 s-代表开始和结束位置。 请注意mainLocalPosZ +
sideCushion
预期会在sideCushion
Z轴上进行sideCushion
。Target is set to the intended Model Renderable.
sideCushion
renderable in this case.目标设置为预期的可渲染模型。 在这种情况下可渲染
sideCushion
。PropertyName and Evaluators are set to
localPosition
and Vector3Evaluator() respectively. Helps in identifying and Evaluating the performed Transformation.PropertyName和Evaluators分别设置为
localPosition
和Vector3Evaluator() 。 帮助识别和评估执行的转换。
Rotational Animation:
旋转动画:
Here,
这里,
ObjectAnimator is set with 2 Quaternions which represent rotational start and end positions. Inputs to
Quaternion.axisAngle()
is a Vector3 and a Degree— representing the axis of rotation and Degree to which rotation happens.ObjectAnimator设置有2个四元数,它们代表旋转的开始和结束位置。
Quaternion.axisAngle()
输入是一个Vector3和一个度数-表示旋转轴和发生旋转的度数。
Why do we use `Quaternion.axisAngle()` instead of just giving Quaternion as Input— It turns out Calculating Quaternions manually is a hectic task — involves a lot a trignomentry. Thus, we use `axisAngle` which handles it for us — giving out the desired Quaternion.
为什么我们使用Quaternion.axisAngle()而不是仅仅提供四元数作为输入-事实证明,手动计算四元数是一项繁重的任务-涉及很多三方面的问题。 因此,我们使用`axisAngle`来为我们处理它-给出所需的四元数。
Target is set to the intended Model Renderable.
mainCushion
renderable in this case.目标设置为预期的可渲染模型。 在这种情况下可渲染的
mainCushion
。PropertyName and Evaluators are set to
localRotation
andQuaternionEvaluator()
respectively. Helps in identifying and Evaluating the performed Transformation.PropertyName和Evaluators设置为
localRotation
和QuaternionEvaluator()
分别。 帮助识别和评估执行的转换。
Hope this helps if you’re planning to work with 3D Animations on Android. Initially, I had a hard time figuring out the exact axis coordinates, you too will. But trust me it becomes easier with time.
如果您打算在Android上使用3D动画,希望对您有所帮助。 最初,您也很难确定确切的轴坐标。 但是请相信我,随着时间的流逝它会变得更加容易。