我正在开发一个基于Unity3D游戏引擎的小型建筑物创建工具。在此工具中,我希望有机会将烟囱放在屋顶上。为了测试在放置过程中烟囱是否在屋顶上,我想从烟囱网格底部的顶点发出一束光线。由于屋顶可以倾斜并且烟囱应该看起来与屋顶对齐,因此我无法测试烟囱的平底。为了能够检测到统一碰撞系统,我必须从网状对撞机外部发送射线。为此,我想执行“虚拟网格切割”,在该网格中平移烟囱网格的底部顶点以匹配屋顶的倾斜度。到目前为止一切顺利。
我当前的解决方案基于以下想法:烟囱网格底部的中心,要平移的顶点和顶点的新位置描述一个三角形。由于我具有屋顶的法线和三角形的两个点(网格的底部中心和顶点的原点),因此我为每个顶点计算了第三点的Y坐标,如下所示:
public static Vector3[] GetVirtualMeshCutVertices(IEnumerable<Vector3> vertices, Vector3 normal)
{
bool xAxisAligned = Math.Abs(normal.z) < Math.Abs(normal.x);
float degreeAngle = (xAxisAligned ? normal.x : normal.z) > 0
? Vector3.Angle(Vector3.up, normal)
: 180 - Vector3.Angle(Vector3.up, normal);
double surfaceAngle = degreeAngle * Math.PI / 180;
double surfaceAngleSin = Math.Sin(surfaceAngle);
double surfaceAngleCos = Math.Cos(surfaceAngle);
return vertices.Select(vector3 =>
GetNewVertexPoint(Vector3.zero, vector3, surfaceAngleCos, surfaceAngleSin, xAxisAligned)).ToArray();
}
private static Vector3 GetNewVertexPoint(Vector3 origin, Vector3 oldVertexPoint, double angleCos,
double angleSin, bool xAxisAligned)
{
var originVec2 = new Vector2(xAxisAligned ? origin.x : origin.z, origin.y);
var oldVertex = new Vector2(xAxisAligned ? oldVertexPoint.x : oldVertexPoint.z, oldVertexPoint.y);
double newYValue = oldVertex.y + (originVec2.x - oldVertex.x) / angleCos * angleSin;
return new Vector3(oldVertexPoint.x, (float) newYValue, oldVertexPoint.z);
}
您可能会看到,该解决方案是直接从2D空间中盗取的。只要屋顶与x轴或z轴对齐,此方法就可以正常工作。但是,一旦我旋转它们,结构就会崩溃。
之后,我尝试旋转顶点以匹配屋顶的法线,并考虑了其他公式以获得“新顶点”。到目前为止没有成功...
因此,也许您有一个主意,如何将该公式与3D空间对齐,或者有一个全新的解决方案来解决我的问题。预先谢谢你:)