diff --git a/Makefile b/Makefile index 8d96dfa..1871115 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ CFLAGS += -march=core2 CFLAGS += -Wall -Werror -Wfatal-errors CFLAGS += -Wno-unused-but-set-variable CFLAGS += -Wno-unknown-pragmas +CFLAGS += -Wno-error=unused-variable CFLAGS += -I./include CFLAGS += -municode LDFLAGS += -municode diff --git a/collada/buffer.py b/collada/buffer.py index bf9d63c..bce7dc2 100644 --- a/collada/buffer.py +++ b/collada/buffer.py @@ -144,7 +144,8 @@ def skin_vertex_buffer(collada, skin, vertex_index_table): def emit(column, cls): for i in range(4): if i >= len(influences): - vertex_buffer.append(cls(0)) + value = cls(0) + vertex_buffer.append(value) else: value = cls(influences[i][column]) assert type(influences[i][column])(value) == influences[i][column] diff --git a/scenes/curve_interpolation/curve_interpolation.DAE b/scenes/curve_interpolation/curve_interpolation.DAE index 2f6ac81..f857d71 100755 --- a/scenes/curve_interpolation/curve_interpolation.DAE +++ b/scenes/curve_interpolation/curve_interpolation.DAE @@ -6,8 +6,8 @@ OpenCOLLADA for 3ds Max; Version: 1.6; Revision: 68 file:///C:/cygwin/home/bilbo/d3d10/scenes/curve_interpolation/curve_interpolation.max - 2026-01-30T09:40:47 - 2026-01-30T09:40:47 + 2026-01-30T14:43:57 + 2026-01-30T14:43:57 Z_UP @@ -1513,12 +1513,12 @@ + + - - @@ -1655,8 +1655,8 @@ - + diff --git a/scenes/curve_interpolation/curve_interpolation.max b/scenes/curve_interpolation/curve_interpolation.max index c8eb44b..4cba6b8 100755 Binary files a/scenes/curve_interpolation/curve_interpolation.max and b/scenes/curve_interpolation/curve_interpolation.max differ diff --git a/src/collada.cpp b/src/collada.cpp index f39a48a..0b5e457 100644 --- a/src/collada.cpp +++ b/src/collada.cpp @@ -314,7 +314,7 @@ namespace collada { XMVECTOR axis = XMVectorSet(0, 1, 0, 0); XMVECTOR axisZ = XMVectorSet(0, 0, 1, 0); XMMATRIX joint0 = XMMatrixScaling(1, 1, 1); - joint0 = XMMatrixTranslation(10, 0, 0) * joint0; + //joint0 = XMMatrixTranslation(10, 0, 0) * joint0; joint0 = XMMatrixRotationNormal(axis, XMConvertToRadians(-90)) * joint0; XMMATRIX joint1 = XMMatrixScaling(1, 1, 1); @@ -332,9 +332,26 @@ namespace collada { = 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]); + + XMFLOAT4X4 foo; + XMStoreFloat4x4(&foo, joint0); + print(" %.1f %.1f %.1f %.1f\n", foo._11, foo._12, foo._13, foo._14); + print(" %.1f %.1f %.1f %.1f\n", foo._21, foo._22, foo._23, foo._24); + print(" %.1f %.1f %.1f %.1f\n", foo._31, foo._32, foo._33, foo._34); + print(" %.1f %.1f %.1f %.1f\n", foo._41, foo._42, foo._43, foo._44); + print("\n"); + + XMStoreFloat4x4(&foo, joint1); + print("joint1ibm:\n"); + print(" %.1f %.1f %.1f %.1f\n", foo._11, foo._12, foo._13, foo._14); + print(" %.1f %.1f %.1f %.1f\n", foo._21, foo._22, foo._23, foo._24); + print(" %.1f %.1f %.1f %.1f\n", foo._31, foo._32, foo._33, foo._34); + print(" %.1f %.1f %.1f %.1f\n", foo._41, foo._42, foo._43, foo._44); + print("\n"); + exit(0); + XMMATRIX mJoints[2] = { joint0ibm * joint0, joint1ibm * joint1, diff --git a/src/collada_scene.cpp b/src/collada_scene.cpp index 29378a9..26e47df 100644 --- a/src/collada_scene.cpp +++ b/src/collada_scene.cpp @@ -19,11 +19,14 @@ namespace collada_scene { ID3D10Effect * g_pEffect = NULL; ID3D10EffectTechnique * g_pTechniqueBlinn = NULL; + ID3D10EffectTechnique * g_pTechniqueBlinnSkin = NULL; ID3D10EffectMatrixVariable * g_pWorldVariable = NULL; ID3D10EffectMatrixVariable * g_pViewVariable = NULL; ID3D10EffectMatrixVariable * g_pProjectionVariable = NULL; + ID3D10EffectMatrixVariable * g_pJointsVariable = NULL; + ID3D10EffectVectorVariable * g_pViewEyeVariable = NULL; ID3D10EffectVectorVariable * g_pLightPosVariable = NULL; ID3D10EffectVectorVariable * g_pLightDirVariable = NULL; @@ -253,7 +256,7 @@ namespace collada_scene { { HRESULT hr; - D3D10_INPUT_ELEMENT_DESC layout[inputs.elements_count + 2]; + D3D10_INPUT_ELEMENT_DESC layout[inputs.elements_count + skin_inputs.elements_count]; UINT byte_offset = 0; for (int i = 0; i < inputs.elements_count; i++) { @@ -291,7 +294,7 @@ namespace collada_scene { layout[ix].SemanticName = skin_inputs.elements[i].semantic; layout[ix].SemanticIndex = skin_inputs.elements[i].semantic_index; layout[ix].Format = dxgi_format(skin_inputs.elements[i].format); - layout[ix].InputSlot = 0; + layout[ix].InputSlot = 1; layout[ix].AlignedByteOffset = skin_byte_offset; layout[ix].InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA; layout[ix].InstanceDataStepRate = 0; @@ -299,6 +302,8 @@ namespace collada_scene { skin_byte_offset += format_size(skin_inputs.elements[i].format); } + g_pTechniqueBlinnSkin->GetPassByIndex(0)->GetDesc(&passDesc); + hr = g_pd3dDevice->CreateInputLayout(layout, inputs.elements_count + skin_inputs.elements_count, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, @@ -335,11 +340,14 @@ namespace collada_scene { } g_pTechniqueBlinn = g_pEffect->GetTechniqueByName("Blinn"); + g_pTechniqueBlinnSkin = g_pEffect->GetTechniqueByName("BlinnSkin"); g_pWorldVariable = g_pEffect->GetVariableByName("World")->AsMatrix(); g_pViewVariable = g_pEffect->GetVariableByName("View")->AsMatrix(); g_pProjectionVariable = g_pEffect->GetVariableByName("Projection")->AsMatrix(); + g_pJointsVariable = g_pEffect->GetVariableByName("Joints")->AsMatrix(); + g_pViewEyeVariable = g_pEffect->GetVariableByName("ViewEye")->AsVector(); g_pLightPosVariable = g_pEffect->GetVariableByName("LightPos")->AsVector(); g_pLightDirVariable = g_pEffect->GetVariableByName("LightDir")->AsVector(); @@ -497,9 +505,6 @@ namespace collada_scene { mesh const& mesh = geometry.mesh; g_pd3dDevice->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R32_UINT, mesh.index_buffer_offset); - D3D10_TECHNIQUE_DESC techDesc; - g_pTechniqueBlinn->GetDesc(&techDesc); - for (int j = 0; j < instance_materials_count; j++) { instance_material const& instance_material = instance_materials[j]; triangles const& triangles = mesh.triangles[instance_material.element_index]; @@ -524,9 +529,6 @@ namespace collada_scene { mesh const& mesh = skin.geometry->mesh; g_pd3dDevice->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R32_UINT, mesh.index_buffer_offset); - D3D10_TECHNIQUE_DESC techDesc; - g_pTechniqueBlinn->GetDesc(&techDesc); - for (int j = 0; j < instance_materials_count; j++) { instance_material const& instance_material = instance_materials[j]; triangles const& triangles = mesh.triangles[instance_material.element_index]; @@ -539,7 +541,7 @@ namespace collada_scene { g_pd3dDevice->IASetVertexBuffers(0, numBuffers, m_pVertexBuffers, strides, offsets); g_pd3dDevice->IASetInputLayout(m_pSkinnedVertexLayouts[triangles.inputs_index]); - g_pTechniqueBlinn->GetPassByIndex(0)->Apply(0); + g_pTechniqueBlinnSkin->GetPassByIndex(0)->Apply(0); g_pd3dDevice->DrawIndexed(triangles.count * 3, triangles.index_offset, 0); } } @@ -560,6 +562,34 @@ namespace collada_scene { { for (int i = 0; i < instance_controllers_count; i++) { instance_controller const &instance_controller = instance_controllers[i]; + skin const &skin = instance_controller.controller->skin; + +#if 0 + float Joints[] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + -0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + + 1.0, 0.0, 0.0, 0.0, + 0.0, 0.7, -0.7, 0.0, + -0.0, 0.7, 0.7, 0.0, + -0.0, -7.5, 3.3, 1.0, + }; +#else + XMFLOAT4X4 Joints[instance_controller.joint_count]; + + for (int joint_index = 0; joint_index < instance_controller.joint_count; joint_index++) { + XMMATRIX ibm = XMLoadFloat4x4((XMFLOAT4X4*)&skin.inverse_bind_matrices[joint_index]); + int node_index = instance_controller.joint_node_indices[joint_index]; + node_instance& node_instance = m_nodeInstances[node_index]; + + XMStoreFloat4x4(&Joints[joint_index], ibm * node_instance.world); + } +#endif + + g_pJointsVariable->SetMatrixArray((float *)Joints, 0, instance_controller.joint_count); + render_skin(instance_controller.controller->skin, instance_controller.instance_materials, instance_controller.instance_materials_count); diff --git a/src/effect/collada_scene.fx b/src/effect/collada_scene.fx index f9cc282..0adde45 100644 --- a/src/effect/collada_scene.fx +++ b/src/effect/collada_scene.fx @@ -15,6 +15,11 @@ cbuffer cbMultiplePerFrame matrix World; }; +cbuffer cbMultiplePerController +{ + matrix Joints[16]; +}; + cbuffer cbPerMaterial { float4 Emission; @@ -37,6 +42,15 @@ SamplerState samLinear { AddressV = Wrap; }; +struct VS_INPUT_SKINNED +{ + float3 Pos : POSITION; + float3 Norm : NORMAL; + float2 Tex : TEXCOORD0; + int4 Joint : BLENDINDICES0; + float4 Weight: BLENDWEIGHT0; +}; + struct VS_INPUT { float3 Pos : POSITION; @@ -52,6 +66,30 @@ struct PS_INPUT float4 WPos : POSITION; }; +PS_INPUT VSSkin(VS_INPUT_SKINNED input) +{ + PS_INPUT output; + + matrix mSkin + = input.Weight.x * Joints[input.Joint.x] + + input.Weight.y * Joints[input.Joint.y] + + input.Weight.z * Joints[input.Joint.z] + + input.Weight.w * Joints[input.Joint.w] + ; + + float4 world_pos = mul(float4(input.Pos, 1), mSkin); + //float4 world_pos = mul(float4(input.Pos, 1), World); + output.Pos = mul(world_pos, View); + output.Pos = mul(output.Pos, Projection); + + output.Norm = mul(input.Norm, (float3x3)World); + output.Tex = input.Tex; + + output.WPos = world_pos; + + return output; +} + PS_INPUT VS(VS_INPUT input) { PS_INPUT output; @@ -84,7 +122,7 @@ float4 PS(PS_INPUT input) : SV_Target for (int i = 0; i < 2; i++) { float3 light_dir = normalize(-LightDir[i].xyz); - float diffuse_intensity = max(dot(normal, light_dir), 0.0); + float diffuse_intensity = max(dot(normal, light_dir), 0.0) + 0.2; float distance = length(LightPos[i].xyz - input.WPos.xyz); float attenuation = 1.0 / (0.002 * distance * distance); @@ -117,3 +155,15 @@ technique10 Blinn SetDepthStencilState(EnableDepth, 0); } } + +technique10 BlinnSkin +{ + pass P0 + { + SetVertexShader(CompileShader(vs_4_0, VSSkin())); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, PS())); + SetBlendState(DisableBlending, float4(0.0, 0.0, 0.0, 0.0), 0xffffffff); + SetDepthStencilState(EnableDepth, 0); + } +} diff --git a/src/scenes/curve_interpolation/curve_interpolation.cpp b/src/scenes/curve_interpolation/curve_interpolation.cpp index e0b53f4..957950c 100644 --- a/src/scenes/curve_interpolation/curve_interpolation.cpp +++ b/src/scenes/curve_interpolation/curve_interpolation.cpp @@ -543,15 +543,15 @@ float const array_node_bone002_rotationz_angle_input_array[] = { }; float const array_node_bone002_rotationz_angle_output_array[] = { - 180.0f, - 230.0f, - 180.0f, - 130.0f, - 180.0f, - 230.0f, - 180.0f, - 130.0f, - 180.0f, + 180.0f + 180.0f, + 230.0f + 180.0f, + 180.0f + 180.0f, + 130.0f + 180.0f, + 180.0f + 180.0f, + 230.0f + 180.0f, + 180.0f + 180.0f, + 130.0f + 180.0f, + 180.0f + 180.0f, }; float const array_node_bone002_rotationz_angle_intangent_array[] = { @@ -1652,8 +1652,17 @@ transform const transforms_node_cube[] = { instance_material const instance_geometry_instance_materials_node_cube_0[] = { { - .element_index = 5, // an index into mesh.triangles - .material = &material_material__17_material, + .element_index = 1, // an index into mesh.triangles + .material = &material_material__15_material, + + .emission = { .input_set = -1 }, + .ambient = { .input_set = -1 }, + .diffuse = { .input_set = -1 }, + .specular = { .input_set = -1 }, + }, + { + .element_index = 0, // an index into mesh.triangles + .material = &material_material__16_material, .emission = { .input_set = -1 }, .ambient = { .input_set = -1 }, @@ -1669,6 +1678,15 @@ instance_material const instance_geometry_instance_materials_node_cube_0[] = { .diffuse = { .input_set = -1 }, .specular = { .input_set = -1 }, }, + { + .element_index = 5, // an index into mesh.triangles + .material = &material_material__17_material, + + .emission = { .input_set = -1 }, + .ambient = { .input_set = -1 }, + .diffuse = { .input_set = -1 }, + .specular = { .input_set = -1 }, + }, { .element_index = 2, // an index into mesh.triangles .material = &material_material__19_material, @@ -1682,24 +1700,6 @@ instance_material const instance_geometry_instance_materials_node_cube_0[] = { .element_index = 4, // an index into mesh.triangles .material = &material_material__20_material, - .emission = { .input_set = -1 }, - .ambient = { .input_set = -1 }, - .diffuse = { .input_set = -1 }, - .specular = { .input_set = -1 }, - }, - { - .element_index = 1, // an index into mesh.triangles - .material = &material_material__15_material, - - .emission = { .input_set = -1 }, - .ambient = { .input_set = -1 }, - .diffuse = { .input_set = -1 }, - .specular = { .input_set = -1 }, - }, - { - .element_index = 0, // an index into mesh.triangles - .material = &material_material__16_material, - .emission = { .input_set = -1 }, .ambient = { .input_set = -1 }, .diffuse = { .input_set = -1 }, @@ -1994,8 +1994,8 @@ instance_light const instance_lights_node_geosphere[] = { }; channel const * const node_channels_node_geosphere[] = { - &node_channel_node_geosphere_scale, &node_channel_node_geosphere_inversescaleaxisrotation, + &node_channel_node_geosphere_scale, &node_channel_node_geosphere_scaleaxisrotation, }; @@ -2140,8 +2140,8 @@ int const joint_node_indices_node_box001_geom_box001_skin1[] = { instance_material const instance_controller_instance_materials_node_box001_0[] = { { - .element_index = 1, // an index into mesh.triangles - .material = &material_material__13_material, + .element_index = 0, // an index into mesh.triangles + .material = &material_material__14_material, .emission = { .input_set = -1 }, .ambient = { .input_set = -1 }, @@ -2149,8 +2149,8 @@ instance_material const instance_controller_instance_materials_node_box001_0[] = .specular = { .input_set = -1 }, }, { - .element_index = 0, // an index into mesh.triangles - .material = &material_material__14_material, + .element_index = 1, // an index into mesh.triangles + .material = &material_material__13_material, .emission = { .input_set = -1 }, .ambient = { .input_set = -1 },