问题描述
对于我的游戏,我添加了“画笔”,它是用于创建关卡几何体的 3D 盒子。我想添加将画笔从里到外翻转的功能,让外部变成内部等等。我很确定我知道如何做到这一点,但我想确保这实际上是标准做法。首先,这是我在引擎中的 BrushVolume 的图片:
public void Rebuild()
{
/**
* No faces are present; empty the StaticBrushVolume
*/
if (this.FaceVisibility == BrushVolumeFaceVisibility.None)
{
if (_bufferBinding.Buffer != null)
{
_bufferBinding.Buffer.dispose();
}
this.FaceCount = 0;
_drawCount = 0;
return;
}
this.FaceCount = CountVisibleFaces(this.FaceVisibility);
Vertex[] vertices = new Vertex[this.FaceCount * 6];
float width = this.Width;
float height = this.Height;
float depth = this.Depth;
float uvX = width / (float)this.DiffuseMaterial.Width;
float uvY = height / (float)this.DiffuseMaterial.Height;
float uvZ = depth / (float)this.DiffuseMaterial.Width;
// Generate Front Face
int index = 0;
if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Front))
{
Vector3 normal = new Vector3(0,-1);
vertices[index++] = new Vertex(new Vector3(-width,height,-depth),new Vector2(uvX,0),normal);
vertices[index++] = new Vertex(new Vector3(width,new Vector2(0,-height,uvY),normal);
vertices[index++] = new Vertex(new Vector3(-width,normal);
}
// Generate East Face
if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Left))
{
Vector3 normal = new Vector3(1,0);
vertices[index++] = new Vertex(new Vector3(width,depth),new Vector2(uvZ,normal);
vertices[index++] = new Vertex(new Vector3(width,normal);
}
// Generate South Face
if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Back))
{
Vector3 normal = new Vector3(0,1);
vertices[index++] = new Vertex(new Vector3(width,normal);
}
// Generate West Face
if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Right))
{
Vector3 normal = new Vector3(-1,0);
// Clockwise
vertices[index++] = new Vertex(new Vector3(-width,normal);
vertices[index++] = new Vertex(new Vector3(-width,normal);
// Counter Clockwise
//vertices[index++] = new Vertex(new Vector3(-width,normal);
//vertices[index++] = new Vertex(new Vector3(-width,normal);
//vertices[index++] = new Vertex(new Vector3(-width,normal);
}
// Generate Top Face
if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Top))
{
Vector3 normal = new Vector3(0,1,uvZ),normal);
}
// Generate Bottom Face
if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Bottom))
{
Vector3 normal = new Vector3(0,-1,0);
vertices[index++] = new Vertex(new Vector3(-width,normal);
}
if (this._bufferBinding.Buffer != null)
{
this._bufferBinding.Buffer.dispose();
}
this._drawCount = vertices.Length;
Buffer vertexBuffer = Buffer.Create(Device,BindFlags.VertexBuffer,vertices);
this._bufferBinding = new VertexBufferBinding(vertexBuffer,32,0); // 32 is Vertex Size In Bytes
}
我在那里留下了一张便条,显示了我目前对如何将一张脸从内部翻转到外部的想法。很简单,我想只是反转缠绕顺序。我的引擎默认使用顺时针缠绕,所以如果我将每个面的缠绕反转为逆时针,它会在发动机中显示为内部。这也有效。然而,这可能是一个愚蠢的问题。但这是标准吗?我尝试谷歌搜索 Blender 如何实现“重新计算内部”,但我在网上找不到任何讨论实际实现细节的内容。
有谁知道从外到内翻转面的标准做法是否像反转缠绕顺序一样简单?
解决方法
我相当肯定,反转缠绕顺序是实现这一目标的方式。我还必须反转纹理坐标和法线,以便正确显示纹理。这是一个 gif,显示了我的实施结果:
在那个 gif 中,我只是按一个键来循环切换笔刷体积的“船体模式”。
此示例的源位于 on my pastebin:
这是我如何从外部反转到内部等的简短示例。
if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Front))
{
if (this.HullMode == BrushVolumeHullMode.Interior)
{
Vector3 normal = new Vector3(0,1);
vertices[index++] = new Vertex(new Vector3(-width,height,-depth),new Vector2(0,0),normal);
vertices[index++] = new Vertex(new Vector3(width,new Vector2(uvX,-height,uvY),normal);
vertices[index++] = new Vertex(new Vector3(-width,normal);
}
else
{
Vector3 normal = new Vector3(0,-1);
vertices[index++] = new Vertex(new Vector3(width,normal);
}
}
应该注意的是,我的实现一点也不优雅,因为我将翻转状态硬编码到 if 分支中,具体取决于外壳模式。像 Blender 这样的软件可能有一种更奢侈的方式来做到这一点,因为它们必须迭代更大(和动态)的三角形集。可能有一种奇特的算法来反转缠绕顺序和纹理坐标。但是,我不知道它可能是什么,因为网上没有相关资料。
如果有人知道更好的方法,我真的很想看看。