collada: render animated/skinned cube
This commit is contained in:
parent
e868d33281
commit
27824a0de1
103
collada/mesh.py
103
collada/mesh.py
@ -46,6 +46,7 @@ def mesh_vertex_buffer(collada, mesh):
|
||||
source.technique_common.accessor.stride
|
||||
for input, source in chain.from_iterable(by_offset.values())
|
||||
)
|
||||
vertex_table = []
|
||||
index_table = {}
|
||||
next_output_index = 0
|
||||
index_buffer = []
|
||||
@ -55,7 +56,6 @@ def mesh_vertex_buffer(collada, mesh):
|
||||
|
||||
for vertex_ix in range(triangles.count * 3):
|
||||
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:
|
||||
index_buffer.append(index_table[index_table_key])
|
||||
continue
|
||||
@ -67,15 +67,15 @@ def mesh_vertex_buffer(collada, mesh):
|
||||
# emit vertex attributes for new output index in vertex buffer
|
||||
for offset in used_offsets:
|
||||
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]:
|
||||
print(input.semantic, end=" ")
|
||||
source_stride = source.technique_common.accessor.stride
|
||||
source_index = p_index * source_stride
|
||||
array_slice = source.array_element.floats[source_index:source_index+source_stride]
|
||||
print(array_slice, end=" ")
|
||||
vertex_buffer.extend(array_slice)
|
||||
print()
|
||||
|
||||
"""
|
||||
print("{")
|
||||
for i in range(triangles.count):
|
||||
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])
|
||||
for j in range(vertex_buffer_stride)), end=",\n")
|
||||
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__":
|
||||
import sys
|
||||
@ -92,4 +181,8 @@ if __name__ == "__main__":
|
||||
|
||||
mesh = collada.library_geometries[0].geometries[0].geometric_element
|
||||
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)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
namespace collada {
|
||||
HRESULT LoadEffect();
|
||||
HRESULT LoadMesh();
|
||||
void Render();
|
||||
void Render(float t);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
124
models/skinned_cube/cube.DAE
Executable file
124
models/skinned_cube/cube.DAE
Executable 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>
|
||||
@ -6,8 +6,8 @@
|
||||
<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>
|
||||
</contributor>
|
||||
<created>2026-01-23T23:56:13</created>
|
||||
<modified>2026-01-23T23:56:13</modified>
|
||||
<created>2026-01-24T13:01:29</created>
|
||||
<modified>2026-01-24T13:01:29</modified>
|
||||
<unit name="inch" meter="0.0254"/>
|
||||
<up_axis>Z_UP</up_axis>
|
||||
</asset>
|
||||
@ -126,9 +126,9 @@
|
||||
</technique_common>
|
||||
</source>
|
||||
<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>
|
||||
<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"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
@ -140,8 +140,8 @@
|
||||
<vertex_weights count="24">
|
||||
<input semantic="JOINT" source="#geom-Box001-skin1-joints" offset="0"/>
|
||||
<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>
|
||||
<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>
|
||||
<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>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>
|
||||
</skin>
|
||||
</controller>
|
||||
|
||||
Binary file not shown.
132
src/collada.cpp
132
src/collada.cpp
@ -117,13 +117,87 @@ namespace collada {
|
||||
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;
|
||||
ID3D10EffectTechnique * g_pTechniqueRender = NULL;
|
||||
ID3D10InputLayout * g_pVertexLayout = NULL;
|
||||
|
||||
ID3D10Buffer * g_pVertexBuffer;
|
||||
ID3D10Buffer * g_pVertexBufferPNT;
|
||||
ID3D10Buffer * g_pVertexBufferJW;
|
||||
ID3D10Buffer * g_pIndexBuffer;
|
||||
|
||||
ID3D10EffectMatrixVariable * g_pJointVariable = NULL;
|
||||
|
||||
ID3D10EffectMatrixVariable * g_pWorldVariable = NULL;
|
||||
ID3D10EffectMatrixVariable * g_pViewVariable = NULL;
|
||||
ID3D10EffectMatrixVariable * g_pProjectionVariable = NULL;
|
||||
@ -154,6 +228,8 @@ namespace collada {
|
||||
g_pTechniqueRender = g_pEffect->GetTechniqueByName("Render");
|
||||
|
||||
// variables
|
||||
g_pJointVariable = g_pEffect->GetVariableByName("mJoint")->AsMatrix();
|
||||
|
||||
g_pWorldVariable = g_pEffect->GetVariableByName("World")->AsMatrix();
|
||||
g_pViewVariable = g_pEffect->GetVariableByName("View")->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},
|
||||
{"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},
|
||||
{"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]));
|
||||
|
||||
@ -194,7 +272,19 @@ namespace collada {
|
||||
bd.CPUAccessFlags = 0;
|
||||
bd.MiscFlags = 0;
|
||||
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)) {
|
||||
print("CreateBuffer: D3D10_BIND_VERTEX_BUFFER\n");
|
||||
return hr;
|
||||
@ -215,20 +305,48 @@ namespace collada {
|
||||
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_pViewVariable->SetMatrix((float *)&g_View);
|
||||
g_pProjectionVariable->SetMatrix((float *)&g_Projection);
|
||||
|
||||
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->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->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
|
||||
@ -2,11 +2,15 @@ matrix World;
|
||||
matrix View;
|
||||
matrix Projection;
|
||||
|
||||
matrix mJoint[2];
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
float4 Pos : POSITION;
|
||||
float3 Normal : NORMAL;
|
||||
float2 Tex : TEXCOORD0;
|
||||
float4 Joint : BLENDINDICES0;
|
||||
float4 Weight : BLENDWEIGHT0;
|
||||
};
|
||||
|
||||
struct PS_INPUT
|
||||
@ -20,7 +24,15 @@ PS_INPUT VS(VS_INPUT input)
|
||||
{
|
||||
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, Projection);
|
||||
|
||||
|
||||
16
src/main.cpp
16
src/main.cpp
@ -126,8 +126,8 @@ XMFLOAT4 g_vLightColors[2] = {
|
||||
|
||||
//
|
||||
|
||||
XMVECTOR g_Eye = XMVectorSet(0.0f, 0.0f, -2.0f, 1.0f);
|
||||
XMVECTOR g_At = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
XMVECTOR g_Eye = XMVectorSet(0.0f, -30.0f, 15.0f, 1.0f);
|
||||
XMVECTOR g_At = XMVectorSet(0.0f, 0.0f, 15.0f, 1.0f);
|
||||
|
||||
// forward declarations
|
||||
|
||||
@ -1710,15 +1710,15 @@ void Update(float t, float dt)
|
||||
|
||||
// view
|
||||
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,
|
||||
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);
|
||||
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);
|
||||
|
||||
@ -1827,7 +1827,7 @@ void Render(float t, float dt)
|
||||
|
||||
RenderFont(dt);
|
||||
|
||||
collada::Render();
|
||||
collada::Render(t);
|
||||
|
||||
// present
|
||||
g_pSwapChain->Present(0, 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user