当前位置: 首页 > article >正文

Unity 的 Vector3 与 Babylon.js 的 Vector3:使用上的异同

        在 3D 开发中,向量是不可或缺的数学工具,用于表示位置、方向、速度等物理量。Unity 和 Babylon.js 都提供了   Vector3   类来处理三维向量,但它们在实现和使用上有一些异同。本文将详细对比 Unity 的   Vector3   和 Babylon.js 的   Vector3  ,帮助你在不同的开发环境中更好地使用它们。

相同点

基本概念

  • 表示三维空间:两者都用于表示三维空间中的向量或点,包含三个分量:  x  、  y  、  z  。
  • 物理量表示:都可以用于表示位置、方向、速度、加速度等物理量。

常用方法

  • 向量运算:都支持基本的向量运算,如加法、减法、数乘、点乘、叉乘等。
  • 归一化:都有方法将向量归一化为单位向量。
  • 长度计算:都有方法计算向量的长度(  magnitude  )和平方长度(  sqrMagnitude  )。
  • 夹角和距离计算:都有方法计算两个向量之间的夹角(  Angle  )和距离(  Distance  )。
  • 线性插值:都有方法在两个向量之间进行线性插值(  Lerp  )。

不同点 

数据类型 

  • Unity:  Vector3   是一个结构体(  struct  ),属于值类型,存储在栈内存中,传递时会进行值拷贝。
  • Babylon.js:  Vector3   是一个类(  class  ),属于引用类型,存储在堆内存中,传递时传递的是引用。 

        这真的是一个巨大的不同,笔者之前一直用Unity开发,转到Bebyon.js之后,想当然的以为BABYLON.Vector3也是一个结构体,开发时出了很多莫名其妙的情况,这是一个必须重视的问题,在Babylon.js里面,使用BABYLON.Vector3.Lerp的时候如果效果不对,可以考虑对BABYLON.Vector3的x、y、z分别使用BABYLON.Scalar.Lerp可能就能解决问题,因为x、y、z是值传递的,往往会避免一些问题。

四则运算

  • Unity:Vector3 进行了 + 、- 、 * 、 /运算符的重载,你可以让两个Vector3直接像float或者int一样进行加减运算,或者让一个Vector3于一个float或者int进行乘除运算。
  • Babylon.js Vector3 没有对 + 、- 、 * 、 /运算符进行重载,如果你让两个Vector3相加,你会得到一个字符串,哈哈。对于四则运算,Babylon.js提供了add、addInPlace、subtract、subtractInPlace、multiply、multiplyInPlace、scale,scaleInPlace、divide、devideInPlace等一些列方法,有兴趣的可以参看Babylon的官方文档,这里只介绍了一部分。

性能特性

  • Unity:由于   Vector3   是值类型,每次传递或赋值时都会进行值拷贝,这在大量操作时可能会导致性能开销。
  • Babylon.js:由于   Vector3   是引用类型,传递和赋值时只传递引用,性能开销较小,但需要注意引用传递带来的副作用,如修改一个对象会影响所有引用该对象的地方。

 静态属性

  • Unity:提供了一些常用的静态属性,如   zero  、  one  、  up  、  down  、  left  、  right  、  forward  、  back   等,方便快速获取特定方向的向量。
  • Babylon.js:没有提供这么多静态属性,但可以通过   BABYLON.Vector3   的构造函数快速创建常用向量,如   new BABYLON.Vector3(0, 0, 0)  。 

方法实现

  • Unity:方法实现较为丰富,提供了许多便捷的方法和属性,如   magnitude  、  sqrMagnitude  、  normalized   等。
  • Babylon.js:方法实现也较为丰富,但某些方法的命名和实现方式可能与 Unity 有所不同。例如,Babylon.js 中的   length()   方法等价于 Unity 中的   magnitude   属性。 

示例代码

Unity 

using UnityEngine;

public class Vector3Example : MonoBehaviour
{
    void Start()
    {
        Vector3 v1 = new Vector3(1, 0, 0);
        Vector3 v2 = new Vector3(0, 0, 1);

        // 计算向量的长度
        float length1 = v1.magnitude;
        float length2 = v2.magnitude;

        // 计算向量的平方长度
        float sqrLength1 = v1.sqrMagnitude;
        float sqrLength2 = v2.sqrMagnitude;

        // 归一化向量
        Vector3 normalizedV1 = v1.normalized;
        Vector3 normalizedV2 = v2.normalized;

        // 计算两个向量的点积
        float dotProduct = Vector3.Dot(v1, v2);

        // 计算两个向量的叉积
        Vector3 crossProduct = Vector3.Cross(v1, v2);

        // 计算两个向量之间的夹角
        float angle = Vector3.Angle(v1, v2);

        // 计算两个点之间的距离
        float distance = Vector3.Distance(v1, v2);

        // 在两个向量之间进行线性插值
        Vector3 interpolatedVector = Vector3.Lerp(v1, v2, 0.5f);

        Debug.Log("Length1: " + length1);
        Debug.Log("Length2: " + length2);
        Debug.Log("SqrLength1: " + sqrLength1);
        Debug.Log("SqrLength2: " + sqrLength2);
        Debug.Log("Normalized V1: " + normalizedV1);
        Debug.Log("Normalized V2: " + normalizedV2);
        Debug.Log("Dot Product: " + dotProduct);
        Debug.Log("Cross Product: " + crossProduct);
        Debug.Log("Angle: " + angle);
        Debug.Log("Distance: " + distance);
        Debug.Log("Interpolated Vector: " + interpolatedVector);
    }
}

Babylon.js

// 创建场景和引擎
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);
var scene = new BABYLON.Scene(engine);

// 创建向量
var v1 = new BABYLON.Vector3(1, 0, 0);
var v2 = new BABYLON.Vector3(0, 0, 1);

// 计算向量的长度
var length1 = v1.length();
var length2 = v2.length();

// 计算向量的平方长度
var sqrLength1 = v1.lengthSquared();
var sqrLength2 = v2.lengthSquared();

// 归一化向量
var normalizedV1 = v1.normalize();
var normalizedV2 = v2.normalize();

// 计算两个向量的点积
var dotProduct = BABYLON.Vector3.Dot(v1, v2);

// 计算两个向量的叉积
var crossProduct = BABYLON.Vector3.Cross(v1, v2);

// 计算两个向量之间的夹角
var angle = BABYLON.Tools.ToDegrees(BABYLON.Vector3.AngleBetween(v1, v2));

// 计算两个点之间的距离
var distance = v1.distanceTo(v2);

// 在两个向量之间进行线性插值
var interpolatedVector = BABYLON.Vector3.Lerp(v1, v2, 0.5);

console.log("Length1: " + length1);
console.log("Length2: " + length2);
console.log("SqrLength1: " + sqrLength1);
console.log("SqrLength2: " + sqrLength2);
console.log("Normalized V1: " + normalizedV1);
console.log("Normalized V2: " + normalizedV2);
console.log("Dot Product: " + dotProduct);
console.log("Cross Product: " + crossProduct);
console.log("Angle: " + angle);
console.log("Distance: " + distance);
console.log("Interpolated Vector: " + interpolatedVector);

// 开始渲染循环
engine.runRenderLoop(function () {
    scene.render();
});

// 处理窗口大小变化
window.addEventListener("resize", function () {
    engine.resize();
});

 总结

        相似点:两者都提供了丰富的向量运算方法,用于处理三维空间中的向量和点。

        不同点:Unity 的   Vector3   是值类型,性能开销较大但操作简单;Babylon.js 的   Vector3   是引用类型,性能开销较小但需要注意引用传递的副作用。

        根据你的具体需求和使用场景,选择合适的工具和方法可以提高开发效率和性能。希望本文能帮助你在不同的 3D 开发环境中更好地使用   Vector3  。 


http://www.kler.cn/a/499913.html

相关文章:

  • 计算机网络之---子网划分与IP地址
  • 前端学习-事件监听以及案例(二十四)
  • fastadmin插件wanlshop使用方法
  • C++语言的文件操作
  • 《探秘开源多模态神经网络模型:AI 新时代的万能钥匙》
  • Virtualbox7.1.4安装Proxmox
  • React(二)——Admin主页/Orders页面/Category页面
  • Flutter项目适配鸿蒙
  • 微前端介绍
  • 索引页与B+树的关系
  • halcon三维点云数据处理(十)locate_cylinder_3d
  • VS Code的设置功能以及多层级的设置方式与解密
  • 海康机器人IPO,又近了一步
  • 青稞Talk预告!面向自动驾驶与物理世界对齐的视频生成模型
  • PY_11_07
  • 深入详解自然语言处理(NLP)中的语言模型:BERT、GPT及其他预训练模型的原理与应用
  • Qt学习笔记第81到90讲
  • SpringBoot日常:集成Kafka
  • 【深度学习】数据预处理
  • vue3的v-for 与 v-if
  • React setState详细使用总结