Unity3D Matrices & Transform

翻译原文

1可视空间

Unity Shader是怎么知道一个像素该画在哪个位置?下面是先展示一组Cube

image

1-1.操控一组3维坐标

创建一10*10*10的3维Cube数组,并作为UnityMatrices对象的成员变量,接下来显示这些Cube在空间中的位置

    void InitCubeArray()
    {
        for (int i =0 , z = 0; z < generalCount; z++)
        {
            for (int y = 0; y < generalCount; y++)
            {
                for (int x = 0; x < generalCount; x++)
                {
                    cubes[i++] = CreateCubesPoint(x, y, z);
                }
            }
        }
    }
View Code
    Transform CreateCubesPoint(int x, int y, int z)
    {
        GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        cube.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
        cube.transform.localPosition = CreateCoordinate(x, y, z);
        cube.GetComponent<MeshRenderer>().material.color = CreateColor(x, y, z);
        return cube.transform;
    }
View Code

设置每个Cube的位置,都以(0,0,0)为原点,(10-1)*0.5为Center左右两边对称

Vector3 CreateCoordinate(int x, int y, int z)
{
    return new Vector3(
         x - center,
         y - center,
         z - center
     );
 }
View Code

然后再用自身坐标xyz分量与Center的比率初始化颜色rgb。效果如上图1-1

Color CreateColor(int x, int y, int z)
 {
     return new Color(
         (float)x / generalCount,
         (float)y / generalCount,
         (float)z / generalCount
     );
 }
View Code

2空间变换

positionning,rotating,and scaling

Cube数组中每个元素在空间中的变换有可能会有差异,虽然每个Cube变换的细节不同,但它们都需要经过一个方法来变换到空间中的某个坐标点。为此我们可以为所有变换创建一个abstract 基类,包含一个抽象的Applay()成员方法,由具体的变换组件去实现这个方法。

public abstract class Transformation : MonoBehaviour
{
    public abstract Vector3 Apply(Vector3 point);
}
View Code

我们给这个UnityMatrices对象添加这样的组件,同时检索Cube数组每个对象,将其坐标传入这个组件的Apply()方法进行计算得到新坐标并应用,这里始终以(0,0,0)作为每个Cube对象的原点坐标,而不能依赖其实际坐标,因为会每帧实时计算并改变。最后我们用泛型列表存储这种一系列变换组件方便统一计算。

private void Update()
{
    GetComponents<Transformation>(transformations);
    //for (int i = 0; i < cubes.Length; i++)
    //{
    //    cubes[i].localPosition = TransformPoint(cubes[i].localPosition);
    //}
    for (int i =0 , z = 0; z < generalCount; z++)
    {
        for (int y = 0; y < generalCount; y++)
        {
            for (int x = 0; x < generalCount; x++)
            {
                 cubes[i++].localPosition = TransformPoint(x, y, z);
             }
         }
     }
 }
View Code

Vector3 TransformPoint(int x, int y, int z)
{
    Vector3 coordinates = CreateCoordinate(x, y, z);
    for (int i = 0; i < transformations.Count; i++)
    {
        coordinates = transformations[i].Apply(coordinates);
     }

    return coordinates;
 }
View Code

2.1位移

现在来做第一种变换:translation位移,这很简单。首先创建一个继承自Transformation组件子类,并定义一个表示自身位置属性的变量,并实现基类的抽象方法。然后添加给Cube数组对象

public class PositionTransformation : Transformation
{
    public Vector3 position;

    public override Vector3 Apply(Vector3 point)
    {
        return point + position;
     }
 }
View Code

现在可以向UnityMatrices对象添加位置转换组件。这允许我们在不移动UnityMatrices对象的情况下移动数组中每个对象的坐标,所有的变换都发生在其局部空间。

position

位移

2.2缩放

接下来做第二种变换:Scaling缩放,这更简单。

public class ScaleTransformation : Transformation
{
    public Vector3 scale;

    public override Vector3 Apply(Vector3 point)
    {
        point.x *= scale.x;
        point.y *= scale.y;
        point.z *= scale.z;
        return point;
    }
}
View Code

scale

缩放

猜你喜欢

转载自www.cnblogs.com/baolong-chen/p/12058419.html
今日推荐