From d7183c1b39072645070cfc72496f1a31e1be7b96 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Fri, 30 Jan 2026 14:45:11 -0600 Subject: [PATCH] collada_scene: render skinned animation --- Makefile | 1 + collada/buffer.py | 3 +- .../curve_interpolation.DAE | 10 +-- .../curve_interpolation.max | Bin 421888 -> 421888 bytes src/collada.cpp | 21 +++++- src/collada_scene.cpp | 48 ++++++++++--- src/effect/collada_scene.fx | 52 +++++++++++++- .../curve_interpolation.cpp | 68 +++++++++--------- 8 files changed, 151 insertions(+), 52 deletions(-) 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 c8eb44bb08257b3ccf925e31b3240b0635731a2b..4cba6b89b2a9f8e65112317058565531ee9c69aa 100755 GIT binary patch delta 15015 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∨B>^z7aAYiNO0cl$;ZKr#?-?PEx-?tD$;Ouf4%Sd0-28+C;HZ+>a z5UdG>Am}ln1_TGV02zX+tAQ#FT7%-CLPXk77=TlN#)3&XJW#=WdKtji{BA#?WCaI} za5cr9WIb64&$76W_11$#T(E^0R~i4F4KDwl|M2I`h#nt49GWT6MuF9|SB*YcaI3GF zRqs&`rSxdPp2XSH5VIPzl+FD841c?jeBZp|7KYCVWCIEJ?)sZhEgixJd{zKx&F=$D zc#C^bxANHoKE221_Px-xORjiJJ7jQH%5TfXEdUIuxalo!sEs|LsFSqxLl2XdvlG=U=Y#vJ>fW-tyA;@73~bGtoOUoKEZzgn3H$^BbyO;N zf-$G+pmHn)!c{`GSZ$^xi)E2mM{{!+SMc#gg>P$9PE)Plxm@IPJNC4Yc#zEPHxSht zKgim4UD%P3y1&fd&si5p_PRItV)B|i{jmw?XyA{Y@o51E}atO<(_)U%BxwzjCB+ zUp@Y{p9>zW2KQIg-DP!W5sQbhSm>R8WAc0KUT_^Nl@vV%&XuxR{Whd1@>N+3^K?v; zS`h{EwS`4*a5W--&EVO5!_sAF4nKY~qnCR0wA~le( z`b=a1NWcHxUpxN&uigCpubo_NU%xp1Czmt3ym^0pS};Ynq1Y(1C(Srwu+)ZtWtmz# z=`OJD4C||lY!OxyUY4?|E)PE3U=D+G4=1UkhO6g6?nulo&5l#hk!DwXk-a#w=|Tg7 z|9;#zE0XKbB4G3>CAQem8gx!U^aF_xggqv`t4u4{q0}7^UYsA{moxI`SqVa`o~{@dxR%6eJ1gcLtx)|j}Q%G zOPmuHS`t=wDrryKt%L(n?NmIN9p;`#;481Z0_}AOJm_fZ{q>`xtET1?!&UITyb51T z4RG%`fGnWKikaGpDoYV-m#DmZF?}n=uO=PSPI23BpFu)*>h1-bdya41>f#e0tu8Pi z40R9b%o>+khGiDM+^SrLgtVzoa1}xdNGT`FaPyyjG5zEwp46}eOz^Kdp)*5cDcl{iN7^Z_ z?JT5^`4Kb0V0D$F?9^^$$ZcQmq-$;<_6~}zo^30^^{_U708#Z`UO^GbRk7oc+O^gi`t2mki#H~#n=$A9wA9{lk?d-%J*y71YL z&3)=`P5!}o>d8%cX(TTWrTKw0*MELn+!@3nqgD+ut4@dFFo!RFDffH{bNF)MejQd6 zxdwdk*=<|NW{6olbqCr)@dd%raWEU2wi36+J>r_GB6hfxQh1TN`ODmDrk{@hQl{_|g4yWD)I9oLG>z3N7m5J$rSDx48F z!T^w<@_ZPVdXX`e`i=7+`E#?NFMnpAn`v_SP=k+clwvDMWvj|8`qY&$HsQ>EJ5#3V zx{58v=)4SrsMNjXWHhc7W-HlFw*Q$QAAaE{SHAg=(7UMr@B1TvFOvIvx%dyq15X3o zI_EC9O`K`UHg#=EAI95HS*Vuz`A^-y|2K4Hkh*%B;_~qh{Xq)qdE5YILEM1f>6o?j z4fBR8H_mt>NMKGgrx6%Py<*fHd_l65T*7qHo#66syfpay-&TG`AwNJO`-nAVt$g@3 zzFYOAWqZ?ZOo*dp^s1L>x2K*%|d=JTelrzg_m=KEo2mSC*Ud;doU(^SsA1{cm1(zjav1YB{U`F?M;%~)s zpUwq;CP=)Ou%`9(4jFhl=3Dw5Q3XgAFh!W?bD(}ZUtFaN-__$N`ojf!hSWo*m42RV zp1*yJ+Fy!iB~{%_)H z9`LZtyY**cMzCWVf9aOvN;K#6v&SU>S z-}||oj^*PA2iLCsISi?&kNK^u1@JJvCEe@op6~7a_TS6pS21&ed7rw&_F5Nl!2Lz1MEvZZ=Qq^`ol( zP~Gz%{YY#I|0_59Lm&Fk<-CNai;MSKtr>BnVK1MSgU=48 z^n0W~H}}TnJN>ZAPx# delta 6218 zcmZ`-d2rj+o!9mI*}8v{ewS{^x~yB)Wh=I2*^Uocwq*H|kH~i795x}4gt!56*dc+W zAq@$E{5awS0x4V0uvw~RfIya+-RVLnTejP7C(8n}>`ePdm!X|qb~@9t-zQlj9d>_~ zo}b?FeV^~=d%X94tDk9CKhs{l+k!v$@Rhg!eD>O23(gntx~@HFJrNM`x_hwrX=v2 zCm^`91m7wl%0KG_Jl?rCi-ywe9fI6_#MRNQojivEhNU9t%Y7ad(xu_s0)|f%u6=#; z&c4$Ae-(HbzN&Qj4}wobMBCEZ`*(Jusm{_{|0DQP#8;QD{7LY!g|8{yZxa4g$tO!) z0pWgJs`~GiLB*BP7!Qb^SY-oTb0}m9UvlD1P$pcl$W# zOP2QhTKKAjPnS$z2o+*JQ}X{#_(+Q}#TW7T4jdHJ^V)^HRh|t6`-__{BnCK-DUsr0_AbP>B*Kbttw1`#sqUWJ_`Z&0XJzweuP7>wTD?&vK4sXw-7)WoXoK$Ct5;AQdV7Vi~(!*D|3v@LuVK%kSRC znv*Ab`;#4?eR$)uUE4Z%Jo2rhzhCOmd~qvz@WXSde|d51&66KZd~jQt?)Y%`V0Y>D zLs&xuCzR*F`M6(R#q26@1b9sFMYM%^QBL|Mc9uKv5$58)l;M6ZbPZDqk39SUXT63M zxgvu{P}8!IcY%kR^0iSR?#mlk2P!^BBV70c4?J+sJ@=qN=WDHc?#r)09&~Z@x3Ky0 zK(tt;Y4bakrgLbNSh&2r%vGD>-1{WnkH%Y(u=8B%9jKL&tPjhgc70hiR6xWHY#J?M zLc*X}SH{C#eG6l2(jusrt@UQn47R3bS)HC*ueCPq-KutHjCdTuC?Gj9?l=m@?zB1g?=izo9_YfP@{y1JJ8-QOeT|v#Odmi zP(M(ERJ^10_+Kz)!hskh%*REX%WTHkL5VAgH`i@%Jh_HH3ReX7Mdu7Bl1Ef?v z4F8J}O0-l>BUtEg+0ejre@(g)nH=oCzHC+u`X4%U2)PFs^;;`mKx>GF>q?mH_Z{5V zxvjJDUaM-0UolH(4|Ye-6y%%a(!5mGPs#?At#?I`Ze>>y3-7w?u5Z1v;%@6J_V>J4 zI^S@_C2`g#4-E&74SM!$))mZ>0d?1p<|lX0CXTe~wl#%jx-kQ$Z_TrT0^=TMyahu# z#EWA}v!uRJEb~gyTHm7Wulb6&YEbC6m;Gyc;=WC`-Qmn5^L4W(+p+M-rQLWA&;4*= zac!@5r(fQ#T-=x6_tY`G-%wncms+h2@o8&(1{OB7%;{Q+jK9EmCNw>b@{EEWFpB#X zinK;(7fNLq0^vu5ddjiLH52$Wa-udd@V4$)H{QdnONP@^w}11q*dx2!U)!xYXc7*Q zvHLre8M}3Vx9!2L@dpQ#13J7#te7D}n;eX5%+@;RO3tIQb2HO8&bUT&;R$_olJSpF zjx_7ZSo$KVg-md?bHhSYT}aw8*YE0X=VLWP;5~M*2zksf>+=x;tnx8rRzLB zHT?QEd(pA$^0H`FsMyn_$S5t-c9B{Unol{l=#1M^(Y{4PVvhBWs4ZRoo~_o%kUl(a zh!@#NA)H@gJY%#or;QbKkx9C7i1rOR#yi6kUOb=(-4$)<&mj6 zA#U**5aL737^Y*j<>KQKJVqOC*D3z!b|1*UP-*1m=Dk88sdy3k~6eupJ7&3N*RKW}L+=$l3=T(Tx{eNZ83mCE|uhq#7o7=!QKyB8&Z{4K~S)r>P=c6*q`plZ?unQ*t7Sb?TJMx0yh&s1W&P8%YlLwFkR0tA z4tGrI!g;1?!Vnp=woK}x1;#bln3}Rg$J`qVOla8LGR8Cwv%W#nGeG)Ds@tZFsd!Gl zG@vz&HmZXLd3`&XNVz3uIr23-0x08NzFA3xOVu!ASK1zE9s2$fb-+w5cvV|X-mMu~ zmq9*Shj-zGKc)@M==>wV9^)NnoTJ+CCT;VSxw!~HXze_qaY8AR?9fNKv$2>Xu@$a`Y}BfNeM=W`ZEN{Kr`T zihj;XHtX;NB@5RDH)T}`lJyKzwjr&5f(?!~wikgTYwtEoXu=iFvEgynm!(}9Q({^d z9JRJh8$wyqm0CIDW?P+;d#p~PY5Ti^U#E9QL; z>pgMHq#XrIV6-i}q>GI(uAI^o_jPa9g-1aHbMvGrHcnakDaW88IzjtJz_LIg>m4vQ z<&5z$ZPQq=4Pa)OK-L(}TBF01J59O!)wV9ReIx7YRyDMcjvkdcskUz1{O|v;`NPuO z%{R=$eJaN10_^bA#W13SqCzH&5vv1C*>}rZ6(H8vqU`Vr?6p8W=%t@y*wBpDH>r!w zLAIqG!)$Phw&xh%xHdS#cyii6&K!Z=UH&qIhC!a362r)z@V9O>%Q zIQmG(Mng2G4-TlzA#-Rz4j~c_VlI#rzv<0AA^| z0&t?msEX0bRz~JmND@}DO)d$_xg)yuGalMp(3WT=@k=WJJHBOW+foV=HsmK=Y?^k1 z%Z_R6eJV?mc4S%K2+&D7H@aGlYqXba>{jYxj0?QEopz-tXGh1YhNrJPyXn={2GDCZE>IK+lW0J$SE0Vbe41GFb2X9J|(ZEMbJ?7i7zNAvlU+3dra z%xXG)u&?j_o}T5du04owOOi0O5!x12L%YV2vV=A=PN*blS2Fs@_dL5c)4oI)XjfXA zm6j-JPbk7#aZ{Z(Y+{>r$lt5adXg@~2LC_5QqiN*4HkjQxz`peKkJ$ZL%&Pl=4Yo0 zmPA42?xDPcv^z@&M=1A32Arg!kM<8yzCp^90sNG!#~8{$U2W@T-QB|{PE1TZK05k? z;o%cQLr1Ho`5vL)Kv>%eeS$D1h_E4{G`475Nuxi-y4na+T)_q@`v!|YY4)@!bPY7h(9PJ9^HuyF+ z6OMiW2`>Fj`Cziy>vOkc z4WS+YsIs-I3~iL7Q*G}YJAHb7{_>_x7bYjqkB^@n896mPd>qK8ooy;>i^`c)8k)6^ z7Ij0joNWR&mFAdS8&K#&gsDlXM-XL<)+c8hrCP5{>z7h)31i7-v+Ie_UpWCCkm3d8 z|9QMcCvT57n#dgpA11>$?+brOpO{)J~P9-4V}_u8kU7inO;ej^xDSk8j=j z%I3{iip5LQ(@#%KoU3?;HPWfECBSzT#;D31Roh~eJ+3lG2xC~z`V~4qm|vlD5qbdV zkx3a3VWsMAM7X(;`#B4zc-YKw98%!y>};h0Jo}Xu@MiFKM~_LGHi$g9IH1M7(mTNd zmnf)=ttv|!IHk&(B#cnD5ti1;C!bhcyjlS}JNw+s%(Ih|PmYZ}rnbbSWFuh=s`P$D zq%owhL;~?Hr7^@fqjH^J#(E?U72HSbq&kT;VAVA0Y;g3eV~ET1MJSE#G^m+}!# zCIpmdFUqXoQH>-fQzR*gU94_xtY9_wId%4qKrF3sw5zP05Hw0{OreVjgr5WADUMrO zy0(4$Yg@LwG&hGlVQPv4PXI?$St2spPZ)wwf^Fd=*Lh{EOH9Zxw@~bsn}Q~(ozZxh zdP_YD9qiB{l#}7K23OP@*d>(h^xS`5$8hfVa5P^b+8y;?1=V7eg%ldMK@!usQ%%BX zJz^C0oC!`p^YqT0Z|&Ie#@4Mb&(FVDEMAL)8Jx1()NjhXgtjLLjEvH>`X$(aBI;id~0%JzGGVc|zr znw~Bc&Iz1C%#LHuI-x-%G~yydy-M2SRSzI<1c$(!7tApn#$%~iWp${k8> z39i!pDwE;Jkxy4w|ErwsW8<1MbORjdSYIXCzG%*=W&A)PunbksTI zbtEnnzmHbUa6kVEc1(!!E;vcNd{+zAN9rAGj$kN=IWXHrTMYzMDoj)uN;$lh4-!P_ z^DBpo7cXwx_6qP__S?0osi#2i(b3ao{lvAowcYn`syQDys9L?OzH=$^D2e8UOyCEZ z)fJEp0Wm-SLfP+t&?g{xVRJ3ZF6Rq~!Bgm$sj5!-O;3r0ZA6liXbxyVIw%S}s_*AI zzrhU1xMEJ>!j<;HBdZm%ip90*>1QA{l=q5Lx!myzCUi1@H#BxG?1vXN)%4j`zGi^8 z+SQdkRxzVU|1{n6QIGzVp1b!W%oKrp9w-j$uHW{mDh@t$WOnuvq@glPPr!1cqmb&+ zzKWFabBDjFMCmOAQ;&{U$V%XYV~ELOaUqjgK_laEIQwHoDv$R~Rs6UA(JbJ%5?PhZ zw7z3`a7YeFF_2iYRF_{ViG#rpXJ;=Ux35kbj*Rh<29oPsSt0+Osp z_XvA6hS2d4DO9KlW03{KLQn#&bQrmK6&!w+SA_~k2?Uwi4wt1rEXI9%p#UI%JG_CIrXhw;Ouo9|$&eDqosjVAf_ j4?g$+EUx|NKj2fTR2-nv4t1!M0P(K{rNb@wL(TsSHBl?; 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 },