collada: render animated/skinned cube

This commit is contained in:
Zack Buhman 2026-01-24 17:31:01 -06:00
parent e868d33281
commit 27824a0de1
8 changed files with 375 additions and 28 deletions

View File

@ -46,6 +46,7 @@ def mesh_vertex_buffer(collada, mesh):
source.technique_common.accessor.stride source.technique_common.accessor.stride
for input, source in chain.from_iterable(by_offset.values()) for input, source in chain.from_iterable(by_offset.values())
) )
vertex_table = []
index_table = {} index_table = {}
next_output_index = 0 next_output_index = 0
index_buffer = [] index_buffer = []
@ -55,7 +56,6 @@ def mesh_vertex_buffer(collada, mesh):
for vertex_ix in range(triangles.count * 3): for vertex_ix in range(triangles.count * 3):
index_table_key = tuple(triangles.p[vertex_ix * p_stride + offset] for offset in used_offsets) index_table_key = tuple(triangles.p[vertex_ix * p_stride + offset] for offset in used_offsets)
print(index_table_key)
if index_table_key in index_table: if index_table_key in index_table:
index_buffer.append(index_table[index_table_key]) index_buffer.append(index_table[index_table_key])
continue continue
@ -67,15 +67,15 @@ def mesh_vertex_buffer(collada, mesh):
# emit vertex attributes for new output index in vertex buffer # emit vertex attributes for new output index in vertex buffer
for offset in used_offsets: for offset in used_offsets:
p_index = triangles.p[vertex_ix * p_stride + offset] p_index = triangles.p[vertex_ix * p_stride + offset]
if offset == vertex_input.offset:
vertex_table.append(p_index)
for input, source in by_offset[offset]: for input, source in by_offset[offset]:
print(input.semantic, end=" ")
source_stride = source.technique_common.accessor.stride source_stride = source.technique_common.accessor.stride
source_index = p_index * source_stride source_index = p_index * source_stride
array_slice = source.array_element.floats[source_index:source_index+source_stride] array_slice = source.array_element.floats[source_index:source_index+source_stride]
print(array_slice, end=" ")
vertex_buffer.extend(array_slice) vertex_buffer.extend(array_slice)
print()
"""
print("{") print("{")
for i in range(triangles.count): for i in range(triangles.count):
print(", ".join(str(index_buffer[i * 3 + j]) for j in range(3)), end=",\n") print(", ".join(str(index_buffer[i * 3 + j]) for j in range(3)), end=",\n")
@ -85,6 +85,95 @@ def mesh_vertex_buffer(collada, mesh):
print(", ".join(str(vertex_buffer[i * vertex_buffer_stride + j]) print(", ".join(str(vertex_buffer[i * vertex_buffer_stride + j])
for j in range(vertex_buffer_stride)), end=",\n") for j in range(vertex_buffer_stride)), end=",\n")
print("}") print("}")
"""
# vertex table:
# list indices: (output/direct3d) vertex indices
# list values: (input/collada) vertex indices
return vertex_table
def filter_tiny(fs, epsilon=0.00001):
return [f if abs(f) > epsilon else 0 for f in fs]
def matrix_transpose(fs):
return (
fs[0], fs[4], fs[8], fs[12],
fs[1], fs[5], fs[9], fs[13],
fs[2], fs[6], fs[10], fs[14],
fs[3], fs[7], fs[11], fs[15],
)
def matrix_print(fs):
for i, f in enumerate(fs):
print(f"{f:5.01f}f", end=", ")
if i % 4 == 3:
print()
def skin_vertex_buffer(collada, skin, vertex_table):
inverse_bind_matrix_input, = find_semantics(skin.joints.inputs, "INV_BIND_MATRIX")
inverse_bind_matrix_source = collada.lookup(inverse_bind_matrix_input.source, types.SourceCore)
stride = inverse_bind_matrix_source.technique_common.accessor.stride
count = inverse_bind_matrix_source.technique_common.accessor.count
array = inverse_bind_matrix_source.array_element
assert type(inverse_bind_matrix_source.array_element) == types.FloatArray
assert stride == 16
assert array.count == count * stride
# enable to improve inverse bind matrix human-readability
#floats = filter_tiny(array.floats)
inverse_bind_matrices = []
print("static const float inverse_bind_matrices[] = {")
for i in range(count):
offset = stride * i
matrix = matrix_transpose(floats[offset:offset+stride])
matrix_print(matrix)
if i + 1 < count:
print()
print("};")
######################################################################
# vertex weights
######################################################################
max_offset = max(i.offset for i in skin.vertex_weights.inputs)
weights_input, = find_semantics(skin.vertex_weights.inputs, "WEIGHT")
weights_source = collada.lookup(weights_input.source, types.SourceCore)
joints_input, = find_semantics(skin.vertex_weights.inputs, "JOINT")
joints_source = collada.lookup(joints_input.source, types.SourceCore)
assert weights_source.technique_common.accessor.stride == 1
assert joints_source.technique_common.accessor.stride == 1
vertex_weights = defaultdict(int)
v_stride = max_offset + 1
v_offset = 0
vertex_influences = []
for vcount in skin.vertex_weights.vcount:
influences = []
for vi in range(vcount):
joint_index = skin.vertex_weights.v[v_offset + joints_input.offset]
weight_index = skin.vertex_weights.v[v_offset + weights_input.offset]
pprint(weights_source)
weight = weights_source.array_element.floats[weight_index]
influences.append((joint_index, weight))
v_offset += v_stride
vertex_influences.append(influences)
vertex_buffer = []
for vertex_index in vertex_table:
influences = vertex_influences[vertex_index]
def emit(column):
for i in range(4):
if i >= len(influences):
vertex_buffer.append(0)
else:
vertex_buffer.append(influences[i][column])
emit(0) # emit joint int4
emit(1) # emit weight float4
for i, v in enumerate(vertex_buffer):
print(v, end=", ")
if i % 8 == 7:
print()
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
@ -92,4 +181,8 @@ if __name__ == "__main__":
mesh = collada.library_geometries[0].geometries[0].geometric_element mesh = collada.library_geometries[0].geometries[0].geometric_element
assert type(mesh) is types.Mesh assert type(mesh) is types.Mesh
mesh_vertex_buffer(collada, mesh) vertex_table = mesh_vertex_buffer(collada, mesh)
skin = collada.library_controllers[0].controllers[0].control_element
assert type(skin) is types.Skin
skin_vertex_buffer(collada, skin, vertex_table)

View File

@ -6,7 +6,7 @@
namespace collada { namespace collada {
HRESULT LoadEffect(); HRESULT LoadEffect();
HRESULT LoadMesh(); HRESULT LoadMesh();
void Render(); void Render(float t);
} }
#endif #endif

124
models/skinned_cube/cube.DAE Executable file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<library_geometries>
<geometry id="geom-Cube" name="Cube">
<mesh>
<source id="geom-Cube-positions">
<float_array id="geom-Cube-positions-array" count="24">
-0.5 -0.5 -0.5
0.5 -0.5 -0.5
-0.5 0.5 -0.5
0.5 0.5 -0.5
-0.5 -0.5 0.5
0.5 -0.5 0.5
-0.5 0.5 0.5
0.5 0.5 0.5
</float_array>
<technique_common>
<accessor source="#geom-Cube-positions-array" count="8" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
</technique_common>
</source>
<source id="geom-Cube-normals">
<float_array id="geom-Cube-normals-array" count="72">
0 0 -1
0 0 -1
0 0 -1
0 0 -1
0 0 1
0 0 1
0 0 1
0 0 1
0 -1 0
0 -1 0
0 -1 0
0 -1 0
1 0 0
1 0 0
1 0 0
1 0 0
0 1 0
0 1 0
0 1 0
0 1 0
-1 0 0
-1 0 0
-1 0 0
-1 0 0
</float_array>
<technique_common>
<accessor source="#geom-Cube-normals-array" count="24" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
</technique_common>
</source>
<source id="geom-Cube-map1">
<float_array id="geom-Cube-map1-array" count="36">
0 0 0
1 0 0
0 1 0
1 1 0
0 0 0
1 0 0
0 1 0
1 1 0
0 0 0
1 0 0
0 1 0
1 1 0
</float_array>
<technique_common>
<accessor source="#geom-Cube-map1-array" count="12" stride="3">
<param name="S" type="float"/>
<param name="T" type="float"/>
<param name="P" type="float"/>
</accessor>
</technique_common>
</source>
<vertices id="geom-Cube-vertices">
<input semantic="POSITION" source="#geom-Cube-positions"/>
</vertices>
<triangles material="ColorMaterial" count="12">
<input semantic="VERTEX" source="#geom-Cube-vertices" offset="0"/>
<input semantic="NORMAL" source="#geom-Cube-normals" offset="1"/>
<input semantic="TEXCOORD" source="#geom-Cube-map1" offset="2" set="0"/>
<p>
0 0 9 2 1 11 3 2 10
3 2 10 1 3 8 0 0 9
4 4 8 5 5 9 7 6 11
7 6 11 6 7 10 4 4 8
0 8 4 1 9 5 5 10 7
5 10 7 4 11 6 0 8 4
1 12 0 3 13 1 7 14 3
7 14 3 5 15 2 1 12 0
3 16 4 2 17 5 6 18 7
6 18 7 7 19 6 3 16 4
2 20 0 0 21 1 4 22 3
4 22 3 6 23 2 2 20 0
</p>
</triangles>
</mesh>
</geometry>
</library_geometries>
<library_visual_scenes>
<visual_scene id="Scene">
<node id="node-Cube" name="Cube">
<instance_geometry url="#geom-Cube">
</instance_geometry>
</node>
</visual_scene>
</library_visual_scenes>
<scene>
<instance_visual_scene url="#Scene"/>
</scene>
</COLLADA>

View File

@ -6,8 +6,8 @@
<authoring_tool>OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68</authoring_tool> <authoring_tool>OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68</authoring_tool>
<source_data>file:///C:/cygwin/home/bilbo/d3d10/models/skinned_cube/skinned_cube.max</source_data> <source_data>file:///C:/cygwin/home/bilbo/d3d10/models/skinned_cube/skinned_cube.max</source_data>
</contributor> </contributor>
<created>2026-01-23T23:56:13</created> <created>2026-01-24T13:01:29</created>
<modified>2026-01-23T23:56:13</modified> <modified>2026-01-24T13:01:29</modified>
<unit name="inch" meter="0.0254"/> <unit name="inch" meter="0.0254"/>
<up_axis>Z_UP</up_axis> <up_axis>Z_UP</up_axis>
</asset> </asset>
@ -126,9 +126,9 @@
</technique_common> </technique_common>
</source> </source>
<source id="geom-Box001-skin1-weights"> <source id="geom-Box001-skin1-weights">
<float_array id="geom-Box001-skin1-weights-array" count="41">1 0 0 0 0 0 0 0 0 0.2 0.8 0.2 0.8 0.2 0.8 0.2 0.8 0.4 0.6 0.4 0.6 0.4 0.6 0.4 0.6 0.6 0.4 0.6 0.4 0.6 0.4 0.6 0.4 0.8 0.2 0.8 0.2 0.8 0.2 0.8 0.2</float_array> <float_array id="geom-Box001-skin1-weights-array" count="33">1 0.2 0.8 0.2 0.8 0.2 0.8 0.2 0.8 0.4 0.6 0.4 0.6 0.4 0.6 0.4 0.6 0.6 0.4 0.6 0.4 0.6 0.4 0.6 0.4 0.8 0.2 0.8 0.2 0.8 0.2 0.8 0.2</float_array>
<technique_common> <technique_common>
<accessor source="#geom-Box001-skin1-weights-array" count="41" stride="1"> <accessor source="#geom-Box001-skin1-weights-array" count="33" stride="1">
<param name="WEIGHT" type="float"/> <param name="WEIGHT" type="float"/>
</accessor> </accessor>
</technique_common> </technique_common>
@ -140,8 +140,8 @@
<vertex_weights count="24"> <vertex_weights count="24">
<input semantic="JOINT" source="#geom-Box001-skin1-joints" offset="0"/> <input semantic="JOINT" source="#geom-Box001-skin1-joints" offset="0"/>
<input semantic="WEIGHT" source="#geom-Box001-skin1-weights" offset="1"/> <input semantic="WEIGHT" source="#geom-Box001-skin1-weights" offset="1"/>
<vcount>2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2</vcount> <vcount>1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2</vcount>
<v>1 1 0 0 1 2 0 0 1 3 0 0 1 4 0 0 1 0 0 5 1 0 0 6 1 0 0 7 1 0 0 8 1 9 0 10 1 11 0 12 1 13 0 14 1 15 0 16 1 17 0 18 1 19 0 20 1 21 0 22 1 23 0 24 1 25 0 26 1 27 0 28 1 29 0 30 1 31 0 32 1 33 0 34 1 35 0 36 1 37 0 38 1 39 0 40</v> <v>0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 1 0 2 1 3 0 4 1 5 0 6 1 7 0 8 1 9 0 10 1 11 0 12 1 13 0 14 1 15 0 16 1 17 0 18 1 19 0 20 1 21 0 22 1 23 0 24 1 25 0 26 1 27 0 28 1 29 0 30 1 31 0 32</v>
</vertex_weights> </vertex_weights>
</skin> </skin>
</controller> </controller>

Binary file not shown.

View File

@ -117,13 +117,87 @@ namespace collada {
54, 55, 53, 54, 55, 53,
}; };
static const float inverse_bind_matrices[] = {
0.0f, 0.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f,
-10.0f, 0.0f, 0.0f, 1.0f,
};
static const float joints_weights[] = {
0, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 0.2, 0.8, 0, 0,
1, 0, 0, 0, 0.2, 0.8, 0, 0,
1, 0, 0, 0, 0.4, 0.6, 0, 0,
1, 0, 0, 0, 0.4, 0.6, 0, 0,
1, 0, 0, 0, 0.6, 0.4, 0, 0,
1, 0, 0, 0, 0.6, 0.4, 0, 0,
1, 0, 0, 0, 0.8, 0.2, 0, 0,
1, 0, 0, 0, 0.8, 0.2, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 0.2, 0.8, 0, 0,
1, 0, 0, 0, 0.2, 0.8, 0, 0,
1, 0, 0, 0, 0.4, 0.6, 0, 0,
1, 0, 0, 0, 0.4, 0.6, 0, 0,
1, 0, 0, 0, 0.6, 0.4, 0, 0,
1, 0, 0, 0, 0.6, 0.4, 0, 0,
1, 0, 0, 0, 0.8, 0.2, 0, 0,
1, 0, 0, 0, 0.8, 0.2, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 0.2, 0.8, 0, 0,
1, 0, 0, 0, 0.2, 0.8, 0, 0,
1, 0, 0, 0, 0.4, 0.6, 0, 0,
1, 0, 0, 0, 0.4, 0.6, 0, 0,
1, 0, 0, 0, 0.6, 0.4, 0, 0,
1, 0, 0, 0, 0.6, 0.4, 0, 0,
1, 0, 0, 0, 0.8, 0.2, 0, 0,
1, 0, 0, 0, 0.8, 0.2, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
0, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 0.2, 0.8, 0, 0,
1, 0, 0, 0, 0.2, 0.8, 0, 0,
1, 0, 0, 0, 0.4, 0.6, 0, 0,
1, 0, 0, 0, 0.4, 0.6, 0, 0,
1, 0, 0, 0, 0.6, 0.4, 0, 0,
1, 0, 0, 0, 0.6, 0.4, 0, 0,
1, 0, 0, 0, 0.8, 0.2, 0, 0,
1, 0, 0, 0, 0.8, 0.2, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
1, 0, 0, 0, 1.0, 0, 0, 0,
};
ID3D10Effect * g_pEffect = NULL; ID3D10Effect * g_pEffect = NULL;
ID3D10EffectTechnique * g_pTechniqueRender = NULL; ID3D10EffectTechnique * g_pTechniqueRender = NULL;
ID3D10InputLayout * g_pVertexLayout = NULL; ID3D10InputLayout * g_pVertexLayout = NULL;
ID3D10Buffer * g_pVertexBuffer; ID3D10Buffer * g_pVertexBufferPNT;
ID3D10Buffer * g_pVertexBufferJW;
ID3D10Buffer * g_pIndexBuffer; ID3D10Buffer * g_pIndexBuffer;
ID3D10EffectMatrixVariable * g_pJointVariable = NULL;
ID3D10EffectMatrixVariable * g_pWorldVariable = NULL; ID3D10EffectMatrixVariable * g_pWorldVariable = NULL;
ID3D10EffectMatrixVariable * g_pViewVariable = NULL; ID3D10EffectMatrixVariable * g_pViewVariable = NULL;
ID3D10EffectMatrixVariable * g_pProjectionVariable = NULL; ID3D10EffectMatrixVariable * g_pProjectionVariable = NULL;
@ -154,6 +228,8 @@ namespace collada {
g_pTechniqueRender = g_pEffect->GetTechniqueByName("Render"); g_pTechniqueRender = g_pEffect->GetTechniqueByName("Render");
// variables // variables
g_pJointVariable = g_pEffect->GetVariableByName("mJoint")->AsMatrix();
g_pWorldVariable = g_pEffect->GetVariableByName("World")->AsMatrix(); g_pWorldVariable = g_pEffect->GetVariableByName("World")->AsMatrix();
g_pViewVariable = g_pEffect->GetVariableByName("View")->AsMatrix(); g_pViewVariable = g_pEffect->GetVariableByName("View")->AsMatrix();
g_pProjectionVariable = g_pEffect->GetVariableByName("Projection")->AsMatrix(); g_pProjectionVariable = g_pEffect->GetVariableByName("Projection")->AsMatrix();
@ -163,6 +239,8 @@ namespace collada {
{"POSITION" , 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0}, {"POSITION" , 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 , D3D10_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL" , 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL" , 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD" , 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD" , 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"BLENDINDICES", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"BLENDWEIGHT" , 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D10_INPUT_PER_VERTEX_DATA, 0},
}; };
UINT numElements = (sizeof (layout)) / (sizeof (layout[0])); UINT numElements = (sizeof (layout)) / (sizeof (layout[0]));
@ -194,7 +272,19 @@ namespace collada {
bd.CPUAccessFlags = 0; bd.CPUAccessFlags = 0;
bd.MiscFlags = 0; bd.MiscFlags = 0;
initData.pSysMem = vertex_buffer; initData.pSysMem = vertex_buffer;
hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &g_pVertexBuffer); hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &g_pVertexBufferPNT);
if (FAILED(hr)) {
print("CreateBuffer: D3D10_BIND_VERTEX_BUFFER\n");
return hr;
}
bd.Usage = D3D10_USAGE_IMMUTABLE;
bd.ByteWidth = (sizeof (joints_weights));
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
initData.pSysMem = joints_weights;
hr = g_pd3dDevice->CreateBuffer(&bd, &initData, &g_pVertexBufferJW);
if (FAILED(hr)) { if (FAILED(hr)) {
print("CreateBuffer: D3D10_BIND_VERTEX_BUFFER\n"); print("CreateBuffer: D3D10_BIND_VERTEX_BUFFER\n");
return hr; return hr;
@ -215,20 +305,48 @@ namespace collada {
return S_OK; return S_OK;
} }
void Render() void Render(float t)
{ {
XMMATRIX World = XMMatrixScaling(0.1, 0.1, 0.1); XMMATRIX World = XMMatrixScaling(1, 1, 1);
// XMMATRIX XM_CALLCONV XMMatrixRotationNormal(FXMVECTOR NormalAxis, float Angle) noexcept;
//XMConvertToRadians
XMVECTOR axis = XMVectorSet(0, 1, 0, 0);
XMVECTOR axisZ = XMVectorSet(0, 0, 1, 0);
XMMATRIX joint0
= XMMatrixRotationNormal(axis, XMConvertToRadians(-90))
;
XMMATRIX joint1
= XMMatrixRotationNormal(axisZ, sin(t))
* XMMatrixTranslation(10, 0, 0)
* joint0
;
XMMATRIX joint0ibm = XMLoadFloat4x4((XMFLOAT4X4*)&inverse_bind_matrices[0 * 16]);
XMMATRIX joint1ibm = XMLoadFloat4x4((XMFLOAT4X4*)&inverse_bind_matrices[1 * 16]);
XMMATRIX mJoints[2] = {
joint0ibm * joint0,
joint1ibm * joint1,
};
g_pJointVariable->SetMatrixArray((float *)mJoints, 0, 2);
g_pWorldVariable->SetMatrix((float *)&World); g_pWorldVariable->SetMatrix((float *)&World);
g_pViewVariable->SetMatrix((float *)&g_View); g_pViewVariable->SetMatrix((float *)&g_View);
g_pProjectionVariable->SetMatrix((float *)&g_Projection); g_pProjectionVariable->SetMatrix((float *)&g_Projection);
UINT stride[] = { UINT stride[] = {
3 * 3 * 4, 3 * 3 * 4, // position normal texture
4 * 2 * 4, // joint weight
}; };
UINT offset[] = { 0 }; UINT offset[] = { 0, 0 };
ID3D10Buffer * vertex_buffers[] = {
g_pVertexBufferPNT,
g_pVertexBufferJW,
};
g_pd3dDevice->IASetInputLayout(g_pVertexLayout); g_pd3dDevice->IASetInputLayout(g_pVertexLayout);
g_pd3dDevice->IASetVertexBuffers(0, 1, &g_pVertexBuffer, stride, offset); g_pd3dDevice->IASetVertexBuffers(0, 2, vertex_buffers, stride, offset);
g_pd3dDevice->IASetIndexBuffer(g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0); g_pd3dDevice->IASetIndexBuffer(g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

View File

@ -2,11 +2,15 @@ matrix World;
matrix View; matrix View;
matrix Projection; matrix Projection;
matrix mJoint[2];
struct VS_INPUT struct VS_INPUT
{ {
float4 Pos : POSITION; float4 Pos : POSITION;
float3 Normal : NORMAL; float3 Normal : NORMAL;
float2 Tex : TEXCOORD0; float2 Tex : TEXCOORD0;
float4 Joint : BLENDINDICES0;
float4 Weight : BLENDWEIGHT0;
}; };
struct PS_INPUT struct PS_INPUT
@ -20,7 +24,15 @@ PS_INPUT VS(VS_INPUT input)
{ {
PS_INPUT output; PS_INPUT output;
output.Pos = mul(input.Pos, World); matrix mSkin
= input.Weight.x * mJoint[int(input.Joint.x)]
+ input.Weight.y * mJoint[int(input.Joint.y)]
+ input.Weight.z * mJoint[int(input.Joint.z)]
+ input.Weight.w * mJoint[int(input.Joint.w)]
;
output.Pos = mul(input.Pos, mSkin);
output.Pos = mul(output.Pos, World);
output.Pos = mul(output.Pos, View); output.Pos = mul(output.Pos, View);
output.Pos = mul(output.Pos, Projection); output.Pos = mul(output.Pos, Projection);

View File

@ -126,8 +126,8 @@ XMFLOAT4 g_vLightColors[2] = {
// //
XMVECTOR g_Eye = XMVectorSet(0.0f, 0.0f, -2.0f, 1.0f); XMVECTOR g_Eye = XMVectorSet(0.0f, -30.0f, 15.0f, 1.0f);
XMVECTOR g_At = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); XMVECTOR g_At = XMVectorSet(0.0f, 0.0f, 15.0f, 1.0f);
// forward declarations // forward declarations
@ -1710,15 +1710,15 @@ void Update(float t, float dt)
// view // view
XMMATRIX mRotateView XMMATRIX mRotateView
= XMMatrixRotationY(deadzone(g_Joystate.thumbLX) * 3.0f * dt) = XMMatrixRotationX(deadzone(g_Joystate.thumbLY) * 3.0f * dt)
* XMMatrixRotationX(deadzone(g_Joystate.thumbLY) * 3.0f * dt); * XMMatrixRotationZ(deadzone(g_Joystate.thumbLX) * 3.0f * dt);
XMMATRIX mTranslateView = XMMatrixTranslation(deadzone(g_Joystate.thumbRX) * 3.0f * dt, XMMATRIX mTranslateView = XMMatrixTranslation(deadzone(g_Joystate.thumbRX) * 3.0f * dt,
0.0f, deadzone(g_Joystate.thumbRY) * 3.0f * dt,
deadzone(g_Joystate.thumbRY) * 3.0f * dt); 0.0f);
g_Eye = XMVector4Transform(g_Eye, mTranslateView * mRotateView); g_Eye = XMVector4Transform(g_Eye, mTranslateView * mRotateView);
XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); XMVECTOR Up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
g_View = XMMatrixLookAtLH(g_Eye, g_At, Up); g_View = XMMatrixLookAtLH(g_Eye, g_At, Up);
@ -1827,7 +1827,7 @@ void Render(float t, float dt)
RenderFont(dt); RenderFont(dt);
collada::Render(); collada::Render(t);
// present // present
g_pSwapChain->Present(0, 0); g_pSwapChain->Present(0, 0);