您将如何对两个矩阵的位置进行插值?
How would you lerp the positions of two matrices?
在我的代码中,我使用以下代码创建了 2 个矩阵来存储有关两个不同网格的信息:
Mesh mesh;
MeshFilter filter;
public SphereMesh SphereMesh;
public CubeMesh CubeMesh;
public Material pointMaterial;
public Mesh pointMesh;
public List<Matrix4x4> matrices1 = new List<Matrix4x4>();
public List<Matrix4x4> matrices2 = new List<Matrix4x4>();
[Space]
public float normalOffset = 0f;
public float globalScale = 0.1f;
public Vector3 scale = Vector3.one;
public int matricesNumber = 1; //determines which matrices to store info in
public void StorePoints()
{
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
Vector3 scaleVector = scale * globalScale;
// Initialize chunk indexes.
int startIndex = 0;
int endIndex = Mathf.Min(1023, mesh.vertexCount);
int pointCount = 0;
while (pointCount < mesh.vertexCount)
{
// Create points for the current chunk.
for (int i = startIndex; i < endIndex; i++)
{
var position = transform.position + transform.rotation * vertices[i] + transform.rotation * (normals[i].normalized * normalOffset);
var rotation = Quaternion.identity;
pointCount++;
if (matricesNumber == 1)
{
matrices1.Add(Matrix4x4.TRS(position, rotation, scaleVector));
}
if (matricesNumber == 2)
{
matrices2.Add(Matrix4x4.TRS(position, rotation, scaleVector));
}
rotation = transform.rotation * Quaternion.LookRotation(normals[i]);
}
// Modify start and end index to the range of the next chunk.
startIndex = endIndex;
endIndex = Mathf.Min(startIndex + 1023, mesh.vertexCount);
}
}
游戏对象以立方体网格开始,此代码将有关网格的信息存储在 matrices1
中。在代码未显示的其他地方,我有它以便 Mesh 更改为 Sphere 然后将 matricesnumber
更改为 2,然后触发上面的代码以将新 Sphere 网格的信息存储在 matrices2
.
这似乎有效,因为我可以使用像 Graphics.DrawMesh(pointMesh, matrices1[i], pointMaterial, 0);
这样的代码
为立方体网格的每个顶点绘制 1 个网格。我可以使用同一条线(但使用 matrices2[i]
)为 Sphere 网格的每个顶点绘制 1 个网格。
问题:如何在屏幕上为立方体网格的每个顶点绘制网格(信息存储在 matrices1
),然后制作这些顶点网格Lerp
进入球体网格(信息存储在 matrices2
)顶点的位置?
我正在尝试用
之类的东西来破解它
float t = Mathf.Clamp((Time.time % 2f) / 2f, 0f, 1f);
matrices1.position.Lerp(matrices1.position, matrices2.position, t);
但显然这是无效代码。可能的解决方案是什么?谢谢。
Matrix4x4
通常只在特殊情况下使用,直接计算变换矩阵。
You rarely use matrices in scripts; most often using Vector3s
, Quaternions
and functionality of Transform
class is more straightforward. Plain matrices are used in special cases like setting up nonstandard camera projection.
在你的情况下,在我看来你实际上只需要以某种方式存储和访问 position
、rotation
和 scale
.
我建议完全不要使用 Matrix4x4
,而是使用一些简单的东西,例如
// The Serializable makes them actually appear in the Inspector
// which might be very helpful in you case
[Serializable]
public class TransformData
{
public Vector3 position;
public Quaternion rotation;
public Vector3 scale;
}
然后
public List<TransformData> matrices1 = new List<TransformData>();
public List<TransformData> matrices2 = new List<TransformData>();
你可以简单地 lerp over
var lerpedPosition = Vector3.Lerp(matrices1[index].position, matrices2[index].position, lerpFactor);
如果您需要它作为 Matrix4x4
,您仍然可以创建它 ad-hoc,例如
var lerpedMatrix = Matrix4x4.Translation(lerpedPosition);
或者您希望使用这些值。
在我的代码中,我使用以下代码创建了 2 个矩阵来存储有关两个不同网格的信息:
Mesh mesh;
MeshFilter filter;
public SphereMesh SphereMesh;
public CubeMesh CubeMesh;
public Material pointMaterial;
public Mesh pointMesh;
public List<Matrix4x4> matrices1 = new List<Matrix4x4>();
public List<Matrix4x4> matrices2 = new List<Matrix4x4>();
[Space]
public float normalOffset = 0f;
public float globalScale = 0.1f;
public Vector3 scale = Vector3.one;
public int matricesNumber = 1; //determines which matrices to store info in
public void StorePoints()
{
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
Vector3 scaleVector = scale * globalScale;
// Initialize chunk indexes.
int startIndex = 0;
int endIndex = Mathf.Min(1023, mesh.vertexCount);
int pointCount = 0;
while (pointCount < mesh.vertexCount)
{
// Create points for the current chunk.
for (int i = startIndex; i < endIndex; i++)
{
var position = transform.position + transform.rotation * vertices[i] + transform.rotation * (normals[i].normalized * normalOffset);
var rotation = Quaternion.identity;
pointCount++;
if (matricesNumber == 1)
{
matrices1.Add(Matrix4x4.TRS(position, rotation, scaleVector));
}
if (matricesNumber == 2)
{
matrices2.Add(Matrix4x4.TRS(position, rotation, scaleVector));
}
rotation = transform.rotation * Quaternion.LookRotation(normals[i]);
}
// Modify start and end index to the range of the next chunk.
startIndex = endIndex;
endIndex = Mathf.Min(startIndex + 1023, mesh.vertexCount);
}
}
游戏对象以立方体网格开始,此代码将有关网格的信息存储在 matrices1
中。在代码未显示的其他地方,我有它以便 Mesh 更改为 Sphere 然后将 matricesnumber
更改为 2,然后触发上面的代码以将新 Sphere 网格的信息存储在 matrices2
.
这似乎有效,因为我可以使用像 Graphics.DrawMesh(pointMesh, matrices1[i], pointMaterial, 0);
这样的代码
为立方体网格的每个顶点绘制 1 个网格。我可以使用同一条线(但使用 matrices2[i]
)为 Sphere 网格的每个顶点绘制 1 个网格。
问题:如何在屏幕上为立方体网格的每个顶点绘制网格(信息存储在 matrices1
),然后制作这些顶点网格Lerp
进入球体网格(信息存储在 matrices2
)顶点的位置?
我正在尝试用
之类的东西来破解它float t = Mathf.Clamp((Time.time % 2f) / 2f, 0f, 1f);
matrices1.position.Lerp(matrices1.position, matrices2.position, t);
但显然这是无效代码。可能的解决方案是什么?谢谢。
Matrix4x4
通常只在特殊情况下使用,直接计算变换矩阵。
You rarely use matrices in scripts; most often using
Vector3s
,Quaternions
and functionality ofTransform
class is more straightforward. Plain matrices are used in special cases like setting up nonstandard camera projection.
在你的情况下,在我看来你实际上只需要以某种方式存储和访问 position
、rotation
和 scale
.
我建议完全不要使用 Matrix4x4
,而是使用一些简单的东西,例如
// The Serializable makes them actually appear in the Inspector
// which might be very helpful in you case
[Serializable]
public class TransformData
{
public Vector3 position;
public Quaternion rotation;
public Vector3 scale;
}
然后
public List<TransformData> matrices1 = new List<TransformData>();
public List<TransformData> matrices2 = new List<TransformData>();
你可以简单地 lerp over
var lerpedPosition = Vector3.Lerp(matrices1[index].position, matrices2[index].position, lerpFactor);
如果您需要它作为 Matrix4x4
,您仍然可以创建它 ad-hoc,例如
var lerpedMatrix = Matrix4x4.Translation(lerpedPosition);
或者您希望使用这些值。