Microsoft DirectX 8.1 (Visual Basic) |
The following user-defined structure can be used for vertices that will be blended between two matrices.
' ' The flexible vertex format descriptor for this vertex would be: ' ' FVF = (D3DFVF_XYZB1 Or D3DFVF_NORMAL Or D3DFVF_TEX1) ' Type D3DBLENDVERTEX v As D3DVECTOR blend As Single n As D3DVECTOR tu As Single tv As Single End Type
The blend weight must appear after the position and RHW data in the flexible vertex format, and before the vertex normal.
Notice that the preceding vertex format contains only one blending weight value. This is because there will be two world matrices, defined in the D3DTS_WORLD and D3DTS_WORLD1 transform states. The system blends each vertex between these two matrices using the single weight value. For three matrices, only two weights are required, and so on.
Note Defining skin weights is easy. Using a linear function of the distance between joints is good start, but a smoother sigmoid function looks better. Choosing a skin-weight distribution function can result in sharp creases at joints, if desired, by using a large variation in skin weight over a short distance.
You set the transformation matrices between which the system blends by calling the Direct3DDevice8.SetTransform method. Set the first parameter to a D3DTS_WORLD member from the CONST_D3DTRANSFORMSTATETYPE enumeration, and set the second parameter to the address of the matrix to be set.
The following Microsoft® Visual Basic® code example sets two world matrices between which geometry will be blended to create the illusion of a jointed arm.
' For this example, the d3dDevice variable is assumed to be a valid ' reference to a Direct3DDevice8 object for an initialized 3-D scene. ' The dx variable is a valid reference to a DirectX7 object. Dim BendAngle As Single Dim matUpperArm As D3DMATRIX, _ matLowerArm As D3DMATRIX BendAngle = 3.1415926 / 4# ' 45 degrees ' The upper arm is immobile. Use the identity matrix. D3DXMatrixIdentity matUpperArm Call d3dDevice.SetTransform(D3DTS_WORLD, matUpperArm) ' The lower arm rotates about the x-axis, attached to the upper arm. D3DXMatrixRotationX matLowerArm, -nBendAngle Call d3dDevice.SetTransform(D3DTS_WORLD1, matLowerArm)
Setting a blending matrix merely causes the system to cache the matrix for later use; it doesn't instruct the system to begin blending vertices.
Geometry blending is disabled by default. To enable geometry blending, call the Direct3DDevice8.SetRenderState method to set the D3DRS_VERTEXBLEND render state to a value from the CONST_D3DVERTEXBLENDFLAGS enumeration. The following code example shows what this call might look like when setting the render state for a blend between two world matrices.
Call d3dDevice.SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_1WEIGHT)
When D3DRS_VERTEXBLEND is set to any value other than D3DVBF_DISABLE, the system assumes that the appropriate number of blending weights will be included in the vertex format. It is your responsibility to provide a compliant vertex format, and to provide a proper description of that format to the Microsoft® Direct3D® rendering methods.
When enabled, the system performs geometry blending for all objects rendered by the DrawPrimitive rendering methods.