|
在picking演示中, 我们先在MeshNode.Teapot方法中初始化两个材料。当渲染茶壶网格,每个子物体会分别渲染出来,子物体0是没有选到的面,子物体1是选到的面.
首先 unprojected 函数通过鼠标坐标取得对应的3D向量RayPos,(深度从0到Z的值).为了得到射线方向,我们用深度Z创建另一个远距离的向量,然后我们用远距离向量减近距离向量就得到了方向向量raydir. RayPos和RayDir利用 Mesh.Intersect 方法返回相交的信息.再用FaceIndex来改变漫反射材料attribute id从原来的0到1,这样这个表面就赋予了另一材料.Pick 操作在 MeshNode 类中完成.
'MeshNode类
Public Class MeshNode
Implements INode
Private Mesh As Mesh
Private Materials(1) As Material
'MeshNode 类中创建Pick函数
Sub Pick(ByVal x As Single, ByVal y As Single) Implements INode.Pick
Dim vNear As Vector3
Dim vFar As Vector3
Dim RayDir As Vector3
Dim Closest As IntersectInformation
vNear = New Vector3(x, y, 0)
'将鼠标的平面坐标反投影到3D空间中,这还需要指定一个Z深度(即vNear.z,它不是结果中的z,与投影矩阵远近裁剪面有关)
vNear.Unproject(Device.Viewport, Device.Transform.Projection, Device.Transform.View, Device.Transform.World)
vFar = New Vector3(x, y, 1)
vFar.Unproject(Device.Viewport, Device.Transform.Projection, Device.Transform.View, Device.Transform.World)
'计算射线方向
vFar.Subtract(vNear)
If Mesh.Intersect(vNear, vFar, Closest) Then
Dim AttributeBuffer() As Integer
AttributeBuffer = Mesh.LockAttributeBuffer(LockFlags.None)
AttributeBuffer(Closest.FaceIndex) = 1
Mesh.UnlockAttributeBuffer(AttributeBuffer)
End If
End Sub
'分别渲染两子物体
Sub Render() Implements INode.Render
Dim i As Integer
For i = 0 To 1
Device.Material = Materials(i)
Mesh.DrawSubset(i)
Next
End Sub
Public Shared Function Teapot() As MeshNode
Dim MeshNode As New MeshNode()
'用DirectX自带的函数创建一茶壶
MeshNode.Mesh = Microsoft.DirectX.Direct3D.Mesh.Teapot(Device)
'创建0号材质
MeshNode.Materials(0) = New Material()
With MeshNode.Materials(0)
.Ambient = Color.White
.Diffuse = Color.White
.Emissive = Color.White
End With
'创建1号材质
MeshNode.Materials(1) = New Material()
With MeshNode.Materials(1)
.Ambient = Color.Red
.Diffuse = Color.Red
.Emissive = Color.Red
End With
Return MeshNode
End Function
End Class
...
完
|
-
|