meshInstance.cpp 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906
  1. #include "meshInstance.h"
  2. #include "meshContainer.h"
  3. #include "..\..\common_h\animation.h"
  4. #include "..\..\common_h\physics.h"
  5. #include "..\..\common_h\particles.h"
  6. #include "..\..\common_h\corecmds.h"
  7. #include "gmxService.h"
  8. #include "blendShapeMixer.h"
  9. //#ifdef _XBOX
  10. #include "..\xrender\Render.h"
  11. //#endif
  12. #ifdef _XBOX
  13. //Использовать VMX набор инструкций для умножения матриц анимации на матрицы мастер скелета
  14. //и для расчета анимированных OBB модельки
  15. #define USE_XBOX_VMX_MATRIXCODE
  16. #endif
  17. #ifndef STOP_DEBUG
  18. const char * visemesName[] =
  19. { "<1> AA", "<2> AH, h", "<3> AO", "<4> AW OW", "<5> OY UH UW", "<6> EH, AE", "<7> IH,AY", "<8> EY", "<9> y, IY", "<Q> r, ER", "<W> l", "<E> w", "<R> m,p,b", "<T> n,NG,DH,d,g,t,z,ZH,s", "<Y> CH, j, SH", "<U> f,v", "<I> x"};
  20. long debugKeys[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O,','P'};
  21. #endif
  22. IVariable * MeshInstance::texStage0 = NULL;
  23. IVariable * MeshInstance::texStage1 = NULL;
  24. IVariable * MeshInstance::texStage2 = NULL;
  25. IVariable * MeshInstance::texStage3 = NULL;
  26. IVariable* MeshInstance::pShadowColorVar = NULL;
  27. IVariable* MeshInstance::pShadowVar = NULL;
  28. IShadowsService* MeshInstance::shadowSRV = NULL;
  29. #ifndef _XBOX
  30. IVariable * MeshInstance::skinBonesVar = NULL;
  31. #endif
  32. DRAW_FUNCTION MeshInstance::drawFunctions[8];
  33. dword MeshInstance::bDrawFunctionsInited = FALSE;
  34. #ifdef _XBOX
  35. //x360 version
  36. __forceinline dword FrustumSphereTest (const Plane * __restrict frustum, XMVECTOR SphereCenter, XMVECTOR SphereRadius)
  37. {
  38. MESH_ALIGN_16_CHECK(frustum);
  39. MESH_ALIGN_16_CHECK(sizeof(Plane));
  40. XMVECTOR frustumP0;
  41. frustumP0 = __lvx(frustum, 0);
  42. XMVECTOR frustumD0 = XMVectorReplicate(frustum->d);
  43. frustum++;
  44. XMVECTOR frustumP1;
  45. frustumP1 = __lvx(frustum, 0);
  46. XMVECTOR frustumD1 = XMVectorReplicate(frustum->d);
  47. frustum++;
  48. XMVECTOR frustumP2;
  49. frustumP2 = __lvx(frustum, 0);
  50. XMVECTOR frustumD2 = XMVectorReplicate(frustum->d);
  51. frustum++;
  52. XMVECTOR frustumP3;
  53. frustumP3 = __lvx(frustum, 0);
  54. XMVECTOR frustumD3 = XMVectorReplicate(frustum->d);
  55. frustum++;
  56. XMVECTOR frustumP4;
  57. frustumP4 = __lvx(frustum, 0);
  58. XMVECTOR frustumD4 = XMVectorReplicate(frustum->d);
  59. XMVECTOR dist0 = XMVector3Dot(frustumP0, SphereCenter) - frustumD0;
  60. XMVECTOR dist1 = XMVector3Dot(frustumP1, SphereCenter) - frustumD1;
  61. XMVECTOR dist2 = XMVector3Dot(frustumP2, SphereCenter) - frustumD2;
  62. XMVECTOR dist3 = XMVector3Dot(frustumP3, SphereCenter) - frustumD3;
  63. XMVECTOR dist4 = XMVector3Dot(frustumP4, SphereCenter) - frustumD4;
  64. //if (dist0 < -SphereRadius) return FALSE;
  65. XMVECTOR greater0 = XMVectorLess(dist0, -SphereRadius);
  66. XMVECTOR greater1 = XMVectorLess(dist1, -SphereRadius);
  67. XMVECTOR greater2 = XMVectorLess(dist2, -SphereRadius);
  68. XMVECTOR greater3 = XMVectorLess(dist3, -SphereRadius);
  69. XMVECTOR greater4 = XMVectorLess(dist4, -SphereRadius);
  70. XMVECTOR Outside = XMVectorFalseInt();
  71. // Outside the plane?
  72. Outside = XMVectorOrInt( Outside, greater0);
  73. Outside = XMVectorOrInt( Outside, greater1);
  74. Outside = XMVectorOrInt( Outside, greater2);
  75. Outside = XMVectorOrInt( Outside, greater3);
  76. Outside = XMVectorOrInt( Outside, greater4);
  77. // If the sphere is outside any of the planes it is outside.
  78. if ( XMVector4EqualInt( Outside, XMVectorTrueInt()))
  79. {
  80. return FALSE;
  81. }
  82. /*
  83. for(long p = 0; p < 5; p++)
  84. {
  85. float fDist = ((SphereCenter | frustum[p].n) - frustum[p].d);
  86. if(fDist < -SphereRadius)
  87. {
  88. return FALSE;
  89. }
  90. }
  91. */
  92. return TRUE;
  93. }
  94. #else
  95. //pc version
  96. __forceinline dword FrustumSphereTest (const Plane * __restrict frustum, const Vector& SphereCenter, float SphereRadius)
  97. {
  98. MESH_ALIGN_16_CHECK(frustum);
  99. for(long p = 0; p < 5; p++)
  100. {
  101. float fDist = ((SphereCenter | frustum[p].n) - frustum[p].d);
  102. if(fDist < -SphereRadius)
  103. {
  104. return FALSE;
  105. }
  106. }
  107. return TRUE;
  108. }
  109. #endif
  110. MESH_INLINE void SetupShadow(DWORD bShadowReceive)
  111. {
  112. //обрабатываем deffer тень...
  113. if (bShadowReceive)
  114. {
  115. NGRender::pRS->SetupShadowLimiters();
  116. IRenderTarget* pRT = MeshInstance::shadowSRV->GetPostProcessTexture();
  117. //надо поставить реальную тень....
  118. if (MeshInstance::shadowSRV && pRT)
  119. {
  120. MeshInstance::pShadowColorVar->SetVector4(MeshInstance::shadowSRV->GetShadowColor().v4);
  121. MeshInstance::pShadowVar->SetTexture(pRT->AsTexture());
  122. } else
  123. {
  124. MeshInstance::pShadowVar->SetTexture(GMXService::pGS->GetNoShadowTexture());
  125. }
  126. } else
  127. {
  128. //Ставим текстуру - тени нет...
  129. MeshInstance::pShadowVar->SetTexture(GMXService::pGS->GetNoShadowTexture());
  130. }
  131. }
  132. MESH_INLINE void setIndices(const header & msh)
  133. {
  134. #ifdef USE_XBOX_INPLACE_GPU_RESOURCES
  135. NGRender::pRS->SetIndicesD3D(msh.inplaceIB.ptr, 0, 0, NULL);
  136. #else
  137. NGRender::pRS->SetIndices(msh.indexBuffer);
  138. #endif
  139. }
  140. MESH_INLINE void setAnimStream0(const header & msh, dword offsetInStream0InBytes)
  141. {
  142. #ifdef USE_XBOX_INPLACE_GPU_RESOURCES
  143. NGRender::pRS->SetStreamSourceD3D(0, msh.inplaceVBStream0.ptr, sizeof(MeshAnimVertex), offsetInStream0InBytes, 0, NULL);
  144. #else
  145. NGRender::pRS->SetStreamSource(0, msh.stream0, sizeof(MeshAnimVertex), offsetInStream0InBytes);
  146. #endif
  147. }
  148. MESH_INLINE void setAnimStream1(const header & msh, dword offsetInStream1InBytes)
  149. {
  150. #ifdef USE_XBOX_INPLACE_GPU_RESOURCES
  151. NGRender::pRS->SetStreamSourceD3D(1, msh.inplaceVBStream1.ptr, sizeof(MeshAnimBoneID), offsetInStream1InBytes, 0, NULL);
  152. #else
  153. NGRender::pRS->SetStreamSource(1, msh.stream1, sizeof(MeshAnimBoneID), offsetInStream1InBytes);
  154. #endif
  155. }
  156. MESH_INLINE void setStaticStream(const header & msh, dword offsetInVertexBufferInBytes)
  157. {
  158. #ifdef USE_XBOX_INPLACE_GPU_RESOURCES
  159. NGRender::pRS->SetStreamSourceD3D(0, msh.inplaceVBStream0.ptr, sizeof(MeshStaticVertex), offsetInVertexBufferInBytes, 0, NULL);
  160. #else
  161. NGRender::pRS->SetStreamSource(0, msh.stream0, sizeof(MeshStaticVertex), offsetInVertexBufferInBytes);
  162. #endif
  163. }
  164. MESH_INLINE void SetTextures(IBaseTexture** __restrict texPtr)
  165. {
  166. #ifndef STOP_DEBUG
  167. GMX_ShowMode showMode = GMXService::pGS->GetShowMode();
  168. #endif
  169. Assert(GMX_MESH_MAX_TEXTURES_COUNT >= 4);
  170. IBaseTexture* tex = *texPtr;
  171. Assert(tex);
  172. MeshInstance::texStage0->SetTexture(tex);
  173. texPtr++;
  174. tex = *texPtr;
  175. #ifndef STOP_DEBUG
  176. //Если НЕ показать все или показать без нормалей, сбрасывае
  177. if (!(showMode == GMXSM_ALL || showMode == GMXSM_NONORMAL))
  178. {
  179. MeshInstance::texStage1->ResetTexture();
  180. } else
  181. {
  182. Assert(tex);
  183. MeshInstance::texStage1->SetTexture(tex);
  184. }
  185. #else
  186. Assert(tex);
  187. MeshInstance::texStage1->SetTexture(tex);
  188. #endif
  189. texPtr++;
  190. tex = *texPtr;
  191. #ifndef STOP_DEBUG
  192. if (!(showMode == GMXSM_ALL || showMode == GMXSM_NODIFFUSE))
  193. {
  194. MeshInstance::texStage2->SetTexture(GMXService::pGS->getEmptyNormalMap());
  195. } else
  196. {
  197. Assert(tex);
  198. MeshInstance::texStage2->SetTexture(tex);
  199. }
  200. #else
  201. Assert(tex);
  202. MeshInstance::texStage2->SetTexture(tex);
  203. #endif
  204. texPtr++;
  205. tex = *texPtr;
  206. Assert(tex);
  207. MeshInstance::texStage3->SetTexture(tex);
  208. texPtr++;
  209. }
  210. MeshInstance::MeshInstance(IRender* renderService, MeshContainer * _container, const char * debugMeshName, const char* pSourceFile, int Line,
  211. boneGpuData * _pBonesGPUdata, long * _pGeomToAnim_TranslateTable, long * _pAnimToGeom_TranslateTable,
  212. long * _pDynamicTransofrmsBonesID, Matrix * _pDynamicTransofrmsBonesMatrixCache,
  213. MeshParticleOnLocator* _pParticlesPtrCache,
  214. float * _pMorphTargetsWeights, long * _pAnimToGeomBlendShapes_TranslateTable) : subscribedToDeletionEvent(_FL_),
  215. msh(_container->getHeader())
  216. {
  217. #ifndef STOP_DEBUG
  218. debugName = debugMeshName;
  219. #endif
  220. dwCurrentDrawFunc = 0;
  221. if (bDrawFunctionsInited == FALSE)
  222. {
  223. drawFunctions[0] = &MeshInstance::DrawStatic<false, false>;
  224. drawFunctions[1] = &MeshInstance::DrawStatic<true, false>;
  225. drawFunctions[2] = &MeshInstance::DrawStatic<false, true>;
  226. drawFunctions[3] = &MeshInstance::DrawStatic<true, true>;
  227. drawFunctions[4] = &MeshInstance::DrawAnimated<false, false>;
  228. drawFunctions[5] = &MeshInstance::DrawAnimated<true, false>;
  229. drawFunctions[6] = &MeshInstance::DrawAnimated<false, true>;
  230. drawFunctions[7] = &MeshInstance::DrawAnimated<true, true>;
  231. bDrawFunctionsInited = TRUE;
  232. }
  233. pBonesGPUdata = _pBonesGPUdata;
  234. pGeomToAnim_TranslateTable = _pGeomToAnim_TranslateTable;
  235. pAnimToGeom_TranslateTable = _pAnimToGeom_TranslateTable;
  236. pDynamicTransofrmsBonesID = _pDynamicTransofrmsBonesID;
  237. pDynamicTransofrmsBonesMatrixCache = _pDynamicTransofrmsBonesMatrixCache;
  238. pParticlesPtrCache = _pParticlesPtrCache;
  239. pMorphTargetsWeights = _pMorphTargetsWeights;
  240. pAnimToGeomBlendShapes_TranslateTable = _pAnimToGeomBlendShapes_TranslateTable;
  241. if (_container->getHeader().bHaveBlendShapes && _container->getHeader().dwBlendShapeTargetsCount > 0)
  242. {
  243. //api->Trace("phonemes count : %d", _container->getHeader().dwBlendShapeTargetsCount);
  244. Assert(pMorphTargetsWeights);
  245. Assert(pAnimToGeomBlendShapes_TranslateTable);
  246. }
  247. blendShapeMixer = NULL;
  248. szSourceFile = pSourceFile;
  249. iSourceLine = Line;
  250. //Связываем список созданных мешей...
  251. MeshInstance * pRoot = GMXService::pHead;
  252. GMXService::pHead = this;
  253. if (pRoot == NULL)
  254. {
  255. pPrev = NULL;
  256. pNext = NULL;
  257. } else
  258. {
  259. pNext = pRoot;
  260. pPrev = NULL;
  261. pRoot->pPrev = this;
  262. }
  263. pRS = renderService;
  264. if (MeshInstance::texStage0 == NULL)
  265. {
  266. MeshInstance::texStage0 = pRS->GetTechniqueGlobalVariable("GMX_TextureStage0", _FL_);
  267. MeshInstance::texStage1 = pRS->GetTechniqueGlobalVariable("GMX_TextureStage1", _FL_);
  268. MeshInstance::texStage2 = pRS->GetTechniqueGlobalVariable("GMX_TextureStage2", _FL_);
  269. MeshInstance::texStage3 = pRS->GetTechniqueGlobalVariable("GMX_TextureStage3", _FL_);
  270. MeshInstance::pShadowColorVar = GMXService::pGS->GetShadowColor_Variable();
  271. MeshInstance::pShadowVar = GMXService::pGS->GetShadowTex_Variable();
  272. MeshInstance::shadowSRV = GMXService::pGS->GetShadowSrv();
  273. }
  274. #ifndef _XBOX
  275. if (MeshInstance::skinBonesVar == NULL)
  276. {
  277. MeshInstance::skinBonesVar = GMXService::pGS->GetSkinBones_Variable();
  278. }
  279. #endif
  280. container = _container;
  281. localBoundBoxAligned = AlignPtr((GMXBoundBox *)localBoundBoxStorage);
  282. MESH_ALIGN_16_CHECK(localBoundBoxAligned);
  283. globalBoundBoxAligned = AlignPtr((GMXBoundBox *)globalBoundBoxStorage);
  284. MESH_ALIGN_16_CHECK(globalBoundBoxAligned);
  285. globalBoundSphereAligned = AlignPtr((GMXBoundSphere *)globalBoundSphereStorage);
  286. MESH_ALIGN_16_CHECK(globalBoundSphereAligned);
  287. localBoundSphereAligned = AlignPtr((GMXBoundSphere *)localBoundSphereStorage);
  288. MESH_ALIGN_16_CHECK(localBoundSphereAligned);
  289. pAnimation = NULL;
  290. sceneAlphaRef = 0.5f;
  291. refCount = 1;
  292. clrUser = Color (0.0f, 0.0f, 0.0f, 1.0f);
  293. bShadowReceive = TRUE;
  294. bFrustumCull = TRUE;
  295. bDynamicLight = FALSE;
  296. pAnimManager = NULL;
  297. pParticleManager = NULL;
  298. pSoundManager = NULL;
  299. ResetReverseTranslateTables();
  300. ResetAllMorphTargets();
  301. SpoilAnimationCache ();
  302. SpoilTransformationsCache();
  303. SelectDrawFunction();
  304. }
  305. MeshInstance::~MeshInstance()
  306. {
  307. SendDeleteNotifiaction();
  308. DeleteParticles();
  309. //Пересвязываем список
  310. if (pPrev == NULL)
  311. {
  312. Assert(GMXService::pHead = this);
  313. GMXService::pHead = pNext;
  314. } else
  315. {
  316. pPrev->pNext = pNext;
  317. }
  318. if (pNext)
  319. {
  320. pNext->pPrev = pPrev;
  321. }
  322. if (blendShapeMixer)
  323. {
  324. delete blendShapeMixer;
  325. blendShapeMixer = NULL;
  326. }
  327. if (container)
  328. {
  329. container->Release();
  330. container = NULL;
  331. }
  332. if (pAnimation)
  333. {
  334. pAnimation->Release();
  335. pAnimation = NULL;
  336. }
  337. }
  338. void MeshInstance::ResetAllMorphTargets()
  339. {
  340. for (dword i = 0; i < msh.dwBlendShapeTargetsCount; i++)
  341. {
  342. pMorphTargetsWeights[i] = 0.0f;
  343. }
  344. }
  345. void MeshInstance::CreateAnimation(IAnimationScene * pAnimScene, const char * fileName)
  346. {
  347. if (!msh.bAnimated)
  348. {
  349. return;
  350. }
  351. IAnimation * pNewAnim = pAnimScene->Create(fileName, _FL_);
  352. if (!pNewAnim)
  353. {
  354. return;
  355. }
  356. SetAnimation(pNewAnim);
  357. //т.к. вызвали Clone внутри SetAnimation тут релизим
  358. pNewAnim->Release();
  359. pNewAnim = NULL;
  360. }
  361. void MeshInstance::ResetReverseTranslateTables()
  362. {
  363. if (pAnimToGeom_TranslateTable)
  364. {
  365. for (dword i = 0; i < MAX_ANIMATION_BONES; i++)
  366. {
  367. pAnimToGeom_TranslateTable[i] = -1;
  368. }
  369. }
  370. if (pAnimToGeomBlendShapes_TranslateTable)
  371. {
  372. for (dword i = 0; i < MAX_ANIMATION_BONES; i++)
  373. {
  374. pAnimToGeomBlendShapes_TranslateTable[i] = -1;
  375. }
  376. }
  377. }
  378. void MeshInstance::SetAnimation(IAnimationTransform * pAnim)
  379. {
  380. if (!msh.bAnimated)
  381. {
  382. return;
  383. }
  384. if (pAnimation)
  385. {
  386. pAnimation->Release();
  387. pAnimation = NULL;
  388. ResetReverseTranslateTables();
  389. }
  390. if (pAnim)
  391. {
  392. pAnimation = pAnim->Clone();
  393. } else
  394. {
  395. return;
  396. }
  397. dword dwNotFoundBonesCount = 0;
  398. boneDataReadOnly * __restrict bonesData = msh.pBonesInfo.ptr;
  399. dword dwBonesCount = msh.dwBonesCount;
  400. Assert(dwBonesCount < 255);
  401. for (dword i = 0; i < dwBonesCount; i++, bonesData++)
  402. {
  403. //искать по короткому имени
  404. long indexInAnim = pAnimation->FindBoneUseHash (bonesData->name.c_str(), bonesData->name.hashNoCase());
  405. if (indexInAnim < 0)
  406. {
  407. dwNotFoundBonesCount++;
  408. } else
  409. {
  410. Assert(indexInAnim < MAX_ANIMATION_BONES);
  411. pAnimToGeom_TranslateTable[indexInAnim] = i;
  412. }
  413. pGeomToAnim_TranslateTable[i] = indexInAnim;
  414. }
  415. if (dwNotFoundBonesCount > 0)
  416. {
  417. api->Trace("Warning: MeshInstance bind to Animation - %d bones not binded !! Check master skeleton !\n", dwNotFoundBonesCount);
  418. }
  419. nodeTransform * __restrict transform = msh.pDynamicTransformations.ptr;
  420. for (dword i = 0; i < msh.dwDynamicTransformationsCount; i++, transform++)
  421. {
  422. if (transform->boneName.c_str() != NULL)
  423. {
  424. pDynamicTransofrmsBonesID[i] = pAnimation->FindBoneUseHash (transform->boneName.c_str(), transform->boneName.hashNoCase());
  425. continue;
  426. }
  427. pDynamicTransofrmsBonesID[i] = -1;
  428. }
  429. dwNotFoundBonesCount = 0;
  430. blendShapeBoneDescription * __restrict bsBone = msh.pBlendShapeBones.ptr;
  431. for (dword i = 0; i < msh.dwBlendShapeBonesCount; i++, bsBone++)
  432. {
  433. if (bsBone->boneName.c_str() != NULL)
  434. {
  435. long indexInAnim = pAnimation->FindBoneUseHash (bsBone->boneName.c_str(), bsBone->boneName.hashNoCase());
  436. if (indexInAnim < 0)
  437. {
  438. dwNotFoundBonesCount++;
  439. } else
  440. {
  441. Assert(indexInAnim < MAX_ANIMATION_BONES);
  442. pAnimToGeomBlendShapes_TranslateTable[indexInAnim] = i;
  443. }
  444. }
  445. }
  446. if (dwNotFoundBonesCount > 0)
  447. {
  448. api->Trace("Warning: MeshInstance bind to Animation - %d blend shapes bones not binded !! Check master skeleton !\n", dwNotFoundBonesCount);
  449. }
  450. if (blendShapeMixer)
  451. {
  452. blendShapeMixer->RegisterAnimation(pAnimation, DEFAULT_BLENDSHAPE_LEVEL);
  453. }
  454. }
  455. void MeshInstance::UpdateTransformations(IAnimationTransform * pAnim) const
  456. {
  457. dword dwServiceCacheIdx = GMXService::pGS->getCacheFrame();
  458. if (dwServiceCacheIdx == dwTransformationsUpdateCacheIdx)
  459. {
  460. return;
  461. }
  462. dwTransformationsUpdateCacheIdx = dwServiceCacheIdx;
  463. MESH_ALIGN_16_CHECK(msh.pAllTransformations.ptr);
  464. MESH_ALIGN_16_CHECK(sizeof(nodeTransform));
  465. Matrix * __restrict mtxCache = pDynamicTransofrmsBonesMatrixCache;
  466. long * __restrict boneId = pDynamicTransofrmsBonesID;
  467. nodeTransform * __restrict transform = msh.pDynamicTransformations.ptr;
  468. if (!pAnim || msh.bAnimated == false)
  469. {
  470. //обновляем без анимации...
  471. //--------------------------------------
  472. for (dword i = 0; i < msh.dwDynamicTransformationsCount; i++, transform++, mtxCache++)
  473. {
  474. //по идее рутовый нод не может быть динамическим, а только у него невалидный parentIndex
  475. int parentIdx = transform->parentIdx;
  476. Assert(parentIdx >= 0);
  477. nodeTransform * parentTransform = &msh.pAllTransformations.ptr[parentIdx];
  478. Matrix mtxLocalTransform = transform->mtxTransform * parentTransform->mtxLocalTransform;
  479. //сюда пишем, что бы не делать условие для parentTransform->mtxLocalTransform (парентом же может быть как дин. так и стат. трансформация)
  480. //просто как кеш используем
  481. transform->mtxLocalTransform = mtxLocalTransform;
  482. //Сюда пишем, что бы для каждого инстанса сохранить результат
  483. *mtxCache = mtxLocalTransform;
  484. }
  485. return;
  486. }
  487. Matrix mCurrentMtx(false);
  488. for (dword i = 0; i < msh.dwDynamicTransformationsCount; i++, transform++, boneId++, mtxCache++)
  489. {
  490. //Не привязанная трансформация к кости, просто наследует трансформацию
  491. long boneID = *boneId;
  492. if(boneID >= 0)
  493. {
  494. mCurrentMtx = pAnim->GetBoneMatrix(boneID);
  495. } else
  496. {
  497. mCurrentMtx = transform->mtxTransform;
  498. }
  499. //по идее рутовый нод не может быть динамическим, а только у него невалидный parentIndex
  500. int parentIdx = transform->parentIdx;
  501. Assert(parentIdx >= 0);
  502. nodeTransform * parentTransform = &msh.pAllTransformations.ptr[parentIdx];
  503. Matrix mtxLocalTransform = mCurrentMtx * parentTransform->mtxLocalTransform;
  504. //сюда пишем, что бы не делать условие для parentTransform->mtxLocalTransform (парентом же может быть как дин. так и стат. трансформация)
  505. //просто как кеш используем
  506. transform->mtxLocalTransform = mtxLocalTransform;
  507. //Сюда пишем, что бы для каждого инстанса сохранить результат
  508. *mtxCache = mtxLocalTransform;
  509. }
  510. }
  511. const Matrix& MeshInstance::GetNodeLocalTransform (GMXHANDLE handle)
  512. {
  513. /*
  514. if (handle == INVALID_GMXHANDLE)
  515. {
  516. return NULL;
  517. }
  518. */
  519. Assert(handle.index >= 1 && handle.index <= msh.dwLocatorsCount);
  520. dword dwLocIndex = (handle.index-1);
  521. dword dwDynamicTrasformIdx = msh.pLocators.ptr[dwLocIndex].dwDynamicTransformCacheIndex;
  522. if (dwDynamicTrasformIdx == INVALID_OFFSET)
  523. {
  524. //Статическая уже посчитаная есть...
  525. return msh.pLocators.ptr[dwLocIndex].pTransform.ptr->mtxLocalTransform;
  526. }
  527. UpdateTransformations(pAnimation);
  528. return pDynamicTransofrmsBonesMatrixCache[dwDynamicTrasformIdx];
  529. }
  530. void MeshInstance::UpdateAnimation(IAnimationTransform * pAnim) const
  531. {
  532. dword dwServiceCacheIdx = GMXService::pGS->getCacheFrame();
  533. if (dwServiceCacheIdx == dwAnimationUpdateCacheIdx)
  534. {
  535. return;
  536. }
  537. dwAnimationUpdateCacheIdx = dwServiceCacheIdx;
  538. dword dwBonesCount = msh.dwBonesCount;
  539. Assert(dwBonesCount < 255);
  540. Vector boundVectorTempMax = Vector(0.0f, 0.0f, 0.0f);
  541. Vector boundVectorTempMin = Vector(0.0f, 0.0f, 0.0f);
  542. localBoundBoxAligned->vMax.x = -FLT_MAX;
  543. localBoundBoxAligned->vMax.y = -FLT_MAX;
  544. localBoundBoxAligned->vMax.z = -FLT_MAX;
  545. localBoundBoxAligned->padding0 = 0;
  546. localBoundBoxAligned->vMin.x = FLT_MAX;
  547. localBoundBoxAligned->vMin.y = FLT_MAX;
  548. localBoundBoxAligned->vMin.z = FLT_MAX;
  549. localBoundBoxAligned->padding1 = 0;
  550. if (pAnim == NULL)
  551. {
  552. const boneDataReadOnly * __restrict inputBone = msh.pBonesInfo.ptr;
  553. boneGpuData * __restrict gpuData = pBonesGPUdata;
  554. for (dword i = 0; i < dwBonesCount; i++, gpuData++, inputBone++)
  555. {
  556. gpuData->data[0] = Vector4(1.0f, 0.0f, 0.0f, 0.0f);
  557. gpuData->data[1] = Vector4(0.0f, 1.0f, 0.0f, 0.0f);
  558. gpuData->data[2].w = 0.0f;
  559. const Vector4 & bbSphereCenterAndRadius = inputBone->bbSphereCenterAndRadius;
  560. boundVectorTempMax = bbSphereCenterAndRadius.v + bbSphereCenterAndRadius.w;
  561. boundVectorTempMin = bbSphereCenterAndRadius.v - bbSphereCenterAndRadius.w;
  562. localBoundBoxAligned->vMax.Max(boundVectorTempMax);
  563. localBoundBoxAligned->vMax.Min(boundVectorTempMin);
  564. }
  565. return;
  566. }
  567. const long * __restrict translateTable = pGeomToAnim_TranslateTable;
  568. const boneMtxInputReadOnly * __restrict bindPoseMtx = msh.pBonesMatrices.ptr;
  569. const boneDataReadOnly * __restrict inputBone = msh.pBonesInfo.ptr;
  570. const Matrix * __restrict animBones = pAnim->GetBoneMatrices ();
  571. boneGpuData * __restrict gpuData = pBonesGPUdata;
  572. if (animBones == NULL)
  573. {
  574. return;
  575. }
  576. MESH_ALIGN_16_CHECK(sizeof(Matrix));
  577. MESH_ALIGN_16_CHECK(sizeof(boneGpuData));
  578. MESH_ALIGN_16_CHECK(sizeof(boneDataReadOnly));
  579. //MESH_ALIGN_16_CHECK(sizeof(boneCachedData));
  580. MESH_ALIGN_16_CHECK(sizeof(boneMtxInputReadOnly));
  581. MESH_ALIGN_16_CHECK(animBones);
  582. MESH_ALIGN_16_CHECK(gpuData);
  583. MESH_ALIGN_16_CHECK(bindPoseMtx);
  584. MESH_ALIGN_16_CHECK(inputBone);
  585. #ifdef USE_XBOX_VMX_MATRIXCODE
  586. byte * pLocalBoundBoxMin = (byte *)&localBoundBoxAligned->vMin.x;
  587. byte * pLocalBoundBoxMax = (byte *)&localBoundBoxAligned->vMax.x;
  588. MESH_ALIGN_16_CHECK(pLocalBoundBoxMin);
  589. MESH_ALIGN_16_CHECK(pLocalBoundBoxMax);
  590. XMVECTOR localBoundBoxMin_VMX = __lvx(pLocalBoundBoxMin, 0);
  591. XMVECTOR localBoundBoxMax_VMX = __lvx(pLocalBoundBoxMax, 0);
  592. #endif
  593. for (dword i = 0; i < dwBonesCount; i++, bindPoseMtx++, gpuData++, translateTable++, inputBone++)
  594. {
  595. long idx = *translateTable;
  596. if (idx >= 0)
  597. {
  598. const Matrix& mAnimFPU = animBones[idx];
  599. //pRS->DrawMatrix(mAnimFPU * mtxWorld, 0.3f);
  600. #ifdef USE_XBOX_VMX_MATRIXCODE
  601. byte * __restrict pMtxBindPose = (byte*)&bindPoseMtx->mtxBindPose.matrix[0];
  602. XMVECTOR mInitVMX_r0 = __lvx(pMtxBindPose, 0);
  603. pMtxBindPose += sizeof(XMVECTOR);
  604. XMVECTOR mInitVMX_r1 = __lvx(pMtxBindPose, 0);
  605. pMtxBindPose += sizeof(XMVECTOR);
  606. XMVECTOR mInitVMX_r2 = __lvx(pMtxBindPose, 0);
  607. pMtxBindPose += sizeof(XMVECTOR);
  608. XMVECTOR mInitVMX_r3 = __lvx(pMtxBindPose, 0);
  609. byte * __restrict pMtxAnimFPU = (byte*)&mAnimFPU.matrix[0];
  610. XMVECTOR mAnimVMX_r0 = __lvx(pMtxAnimFPU, 0);
  611. pMtxAnimFPU += sizeof(XMVECTOR);
  612. XMVECTOR mAnimVMX_r1 = __lvx(pMtxAnimFPU, 0);
  613. pMtxAnimFPU += sizeof(XMVECTOR);
  614. XMVECTOR mAnimVMX_r2 = __lvx(pMtxAnimFPU, 0);
  615. pMtxAnimFPU += sizeof(XMVECTOR);
  616. XMVECTOR mAnimVMX_r3 = __lvx(pMtxAnimFPU, 0);
  617. //XMMATRIX * mInitVMX = (XMMATRIX *)&bindPoseMtx->mtxBindPose;
  618. //XMMATRIX * mAnimVMX = (XMMATRIX *)&mAnimFPU;
  619. //Готовим кешлинейку куда положить результат...
  620. __dcbt(0, (const void *)&gpuData->data[0]);
  621. //Транспонированная матрица mAnim
  622. XMVECTOR t0 = __vmrghw(mAnimVMX_r0, mAnimVMX_r2);
  623. XMVECTOR t1 = __vmrghw(mAnimVMX_r1, mAnimVMX_r3);
  624. XMVECTOR t2 = __vmrglw(mAnimVMX_r0, mAnimVMX_r2);
  625. XMVECTOR t3 = __vmrglw(mAnimVMX_r1, mAnimVMX_r3);
  626. XMMATRIX mAnimTransposed;
  627. mAnimTransposed.r[0] = __vmrghw(t0, t1);
  628. mAnimTransposed.r[2] = __vmrghw(t2, t3);
  629. mAnimTransposed.r[1] = __vmrglw(t0, t1);
  630. mAnimTransposed.r[3] = __vmrglw(t2, t3);
  631. //Получили mAnimTransposed
  632. //Считаем умножение, двух матриц - но результаты кладуться в вектора а не во float
  633. XMVECTOR v00 = __vmsum4fp(mInitVMX_r0, mAnimTransposed.r[0]);//gpu
  634. XMVECTOR v02 = __vmsum4fp(mInitVMX_r0, mAnimTransposed.r[2]);//only for transform
  635. XMVECTOR v01 = __vmsum4fp(mInitVMX_r0, mAnimTransposed.r[1]);//gpu
  636. XMVECTOR v10 = __vmsum4fp(mInitVMX_r1, mAnimTransposed.r[0]);//gpu
  637. XMVECTOR v12 = __vmsum4fp(mInitVMX_r1, mAnimTransposed.r[2]);//only for transform
  638. XMVECTOR v11 = __vmsum4fp(mInitVMX_r1, mAnimTransposed.r[1]);//gpu
  639. XMVECTOR v20 = __vmsum4fp(mInitVMX_r2, mAnimTransposed.r[0]);//gpu
  640. XMVECTOR v22 = __vmsum4fp(mInitVMX_r2, mAnimTransposed.r[2]);//only for transform
  641. XMVECTOR v21 = __vmsum4fp(mInitVMX_r2, mAnimTransposed.r[1]);//gpu
  642. XMVECTOR v30 = __vmsum4fp(mInitVMX_r3, mAnimTransposed.r[0]);//gpu
  643. XMVECTOR v32 = __vmsum4fp(mInitVMX_r3, mAnimTransposed.r[2]);//gpu
  644. XMVECTOR v31 = __vmsum4fp(mInitVMX_r3, mAnimTransposed.r[1]);//gpu
  645. XMVECTOR _zero = {0.0f, 0.0f, 0.0f, 0.0f};
  646. XMVECTOR _one = {1.0f, 1.0f, 1.0f, 1.0f};
  647. XMVECTOR v00v02 = __vmrghw(v00, v02);
  648. XMVECTOR v01v03 = __vmrghw(v01, _zero);
  649. XMVECTOR v10v12 = __vmrghw(v10, v12);
  650. XMVECTOR v11v13 = __vmrghw(v11, _zero);
  651. XMVECTOR v20v22 = __vmrghw(v20, v22);
  652. XMVECTOR v21v23 = __vmrghw(v21, _zero);
  653. XMVECTOR v30v32 = __vmrghw(v30, v32);
  654. XMVECTOR v31v33 = __vmrghw(v31, _one);
  655. //результирующая матрица mInitVMX*mAnimVMX
  656. XMMATRIX resMatrix;
  657. resMatrix.r[0] = __vmrghw(v00v02, v01v03);
  658. resMatrix.r[1] = __vmrghw(v10v12, v11v13);
  659. resMatrix.r[2] = __vmrghw(v20v22, v21v23);
  660. resMatrix.r[3] = __vmrghw(v30v32, v31v33);
  661. //gpu data...
  662. //-------------------------
  663. //00, 10, 20, 30
  664. //01, 11, 21, 31
  665. // 32
  666. XMVECTOR v00v20 = __vmrghw(v00, v20);
  667. XMVECTOR v10v30 = __vmrghw(v10, v30);
  668. XMVECTOR v01v21 = __vmrghw(v01, v21);
  669. XMVECTOR v11v31 = __vmrghw(v11, v31);
  670. //---------------------------------------------------
  671. //XMVECTOR * _centerLocalVMXptr = (XMVECTOR *)&inputBone->bbSphereCenterAndRadius.x;
  672. //XMVECTOR * _radiusLocalVMXptr = (XMVECTOR *)&inputBone->bbSphereRadius.x;
  673. XMVECTOR centerLocalVMX = __lvx(&inputBone->bbSphereCenterAndRadius.x, 0);
  674. XMVECTOR radiusLocalVMX = __lvx(&inputBone->bbSphereRadius.x, 0);
  675. //XMVECTOR * minLocalVMXptr = (XMVECTOR *)&inputBone->bbMin.x;
  676. //XMVECTOR * maxLocalVMXptr = (XMVECTOR *)&inputBone->bbMax.x;
  677. //XMVECTOR * _centerWorldVMXptr = (XMVECTOR *)&cachedBoneData->bbSphereCenterGlobalAndRadius.x;
  678. //центр сферы посчитали...
  679. XMVECTOR centerWorldVMX = XMVector3Transform(centerLocalVMX, resMatrix);
  680. //XMVECTOR minWorldVMX = XMVector3Transform(*minLocalVMXptr, resMatrix);
  681. //XMVECTOR maxWorldVMX = XMVector3Transform(*maxLocalVMXptr, resMatrix);
  682. //XMVECTOR * maxWorldVMXptr = (XMVECTOR *)&cachedBoneData->bbMaxGlobal.x;
  683. //XMVECTOR * minWorldVMXptr = (XMVECTOR *)&cachedBoneData->bbMinGlobal.x;
  684. //min, max посчитали...
  685. //*maxWorldVMXptr = __vmaxfp(minWorldVMX, maxWorldVMX);
  686. //*minWorldVMXptr = __vminfp(minWorldVMX, maxWorldVMX);
  687. XMVECTOR boundVectorTempVMX_Max = __vaddfp(centerWorldVMX, radiusLocalVMX);
  688. XMVECTOR boundVectorTempVMX_Min = __vsubfp(centerWorldVMX, radiusLocalVMX);
  689. localBoundBoxMax_VMX = __vmaxfp(localBoundBoxMax_VMX, boundVectorTempVMX_Max);
  690. localBoundBoxMin_VMX = __vminfp(localBoundBoxMin_VMX, boundVectorTempVMX_Min);
  691. XMVECTOR * gpuDataVMX = (XMVECTOR *)&gpuData->data[0];
  692. gpuDataVMX[0] = __vmrghw(v00v20, v10v30);
  693. gpuDataVMX[1] = __vmrghw(v01v21, v11v31);
  694. gpuDataVMX[2].w = v32.x;
  695. #else
  696. //FPU код
  697. const Matrix & mtxBindPoseFPU = bindPoseMtx->mtxBindPose;
  698. //Эти значения нужно будет сохранить в gpuData
  699. float v00FPU = mAnimFPU.m[0][0] * mtxBindPoseFPU.m[0][0] + mAnimFPU.m[1][0] * mtxBindPoseFPU.m[0][1] + mAnimFPU.m[2][0] * mtxBindPoseFPU.m[0][2];
  700. float v10FPU = mAnimFPU.m[0][0] * mtxBindPoseFPU.m[1][0] + mAnimFPU.m[1][0] * mtxBindPoseFPU.m[1][1] + mAnimFPU.m[2][0] * mtxBindPoseFPU.m[1][2];
  701. float v20FPU = mAnimFPU.m[0][0] * mtxBindPoseFPU.m[2][0] + mAnimFPU.m[1][0] * mtxBindPoseFPU.m[2][1] + mAnimFPU.m[2][0] * mtxBindPoseFPU.m[2][2];
  702. float v30FPU = mAnimFPU.m[0][0] * mtxBindPoseFPU.m[3][0] + mAnimFPU.m[1][0] * mtxBindPoseFPU.m[3][1] + mAnimFPU.m[2][0] * mtxBindPoseFPU.m[3][2] + mAnimFPU.m[3][0];
  703. float v01FPU = mAnimFPU.m[0][1] * mtxBindPoseFPU.m[0][0] + mAnimFPU.m[1][1] * mtxBindPoseFPU.m[0][1] + mAnimFPU.m[2][1] * mtxBindPoseFPU.m[0][2];
  704. float v11FPU = mAnimFPU.m[0][1] * mtxBindPoseFPU.m[1][0] + mAnimFPU.m[1][1] * mtxBindPoseFPU.m[1][1] + mAnimFPU.m[2][1] * mtxBindPoseFPU.m[1][2];
  705. float v21FPU = mAnimFPU.m[0][1] * mtxBindPoseFPU.m[2][0] + mAnimFPU.m[1][1] * mtxBindPoseFPU.m[2][1] + mAnimFPU.m[2][1] * mtxBindPoseFPU.m[2][2];
  706. float v31FPU = mAnimFPU.m[0][1] * mtxBindPoseFPU.m[3][0] + mAnimFPU.m[1][1] * mtxBindPoseFPU.m[3][1] + mAnimFPU.m[2][1] * mtxBindPoseFPU.m[3][2] + mAnimFPU.m[3][1];
  707. float v32FPU = mAnimFPU.m[0][2] * mtxBindPoseFPU.m[3][0] + mAnimFPU.m[1][2] * mtxBindPoseFPU.m[3][1] + mAnimFPU.m[2][2] * mtxBindPoseFPU.m[3][2] + mAnimFPU.m[3][2];
  708. //Эти значения нужны только для умножения на вектор...
  709. float v02FPU = mAnimFPU.m[0][2] * mtxBindPoseFPU.m[0][0] + mAnimFPU.m[1][2] * mtxBindPoseFPU.m[0][1] + mAnimFPU.m[2][2] * mtxBindPoseFPU.m[0][2];
  710. float v12FPU = mAnimFPU.m[0][2] * mtxBindPoseFPU.m[1][0] + mAnimFPU.m[1][2] * mtxBindPoseFPU.m[1][1] + mAnimFPU.m[2][2] * mtxBindPoseFPU.m[1][2];
  711. float v22FPU = mAnimFPU.m[0][2] * mtxBindPoseFPU.m[2][0] + mAnimFPU.m[1][2] * mtxBindPoseFPU.m[2][1] + mAnimFPU.m[2][2] * mtxBindPoseFPU.m[2][2];
  712. //Vector4 & centerWorldFPU = cachedBoneData->bbSphereCenterGlobalAndRadius;
  713. //Vector4 & minGlobalFPU = cachedBoneData->bbMinGlobal;
  714. //Vector4 & maxGlobalFPU = cachedBoneData->bbMaxGlobal;
  715. Vector4 minGlobalFPU_temp;
  716. Vector4 maxGlobalFPU_temp;
  717. const Vector4 & centerLocalFPU = inputBone->bbSphereCenterAndRadius;
  718. //const Vector & minLocalFPU = inputBone->bbMin;
  719. //const Vector & maxLocalFPU = inputBone->bbMax;
  720. //Вектор на матрицу
  721. Vector4 tmp;
  722. tmp.x = v00FPU * centerLocalFPU.x + v10FPU * centerLocalFPU.y + v20FPU * centerLocalFPU.z + v30FPU;
  723. tmp.y = v01FPU * centerLocalFPU.x + v11FPU * centerLocalFPU.y + v21FPU * centerLocalFPU.z + v31FPU;
  724. tmp.z = v02FPU * centerLocalFPU.x + v12FPU * centerLocalFPU.y + v22FPU * centerLocalFPU.z + v32FPU;
  725. //centerWorldFPU.w = centerLocalFPU.w;
  726. boundVectorTempMax = tmp.v + centerLocalFPU.w;
  727. boundVectorTempMin = tmp.v - centerLocalFPU.w;
  728. localBoundBoxAligned->vMax.Max(boundVectorTempMax);
  729. localBoundBoxAligned->vMin.Min(boundVectorTempMin);
  730. //Вектор на матрицу
  731. //minGlobalFPU_temp.x = v00FPU * minLocalFPU.x + v10FPU * minLocalFPU.y + v20FPU * minLocalFPU.z + v30FPU;
  732. //minGlobalFPU_temp.y = v01FPU * minLocalFPU.x + v11FPU * minLocalFPU.y + v21FPU * minLocalFPU.z + v31FPU;
  733. //minGlobalFPU_temp.z = v02FPU * minLocalFPU.x + v12FPU * minLocalFPU.y + v22FPU * minLocalFPU.z + v32FPU;
  734. //Вектор на матрицу
  735. //maxGlobalFPU_temp.x = v00FPU * maxLocalFPU.x + v10FPU * maxLocalFPU.y + v20FPU * maxLocalFPU.z + v30FPU;
  736. //maxGlobalFPU_temp.y = v01FPU * maxLocalFPU.x + v11FPU * maxLocalFPU.y + v21FPU * maxLocalFPU.z + v31FPU;
  737. //maxGlobalFPU_temp.z = v02FPU * maxLocalFPU.x + v12FPU * maxLocalFPU.y + v22FPU * maxLocalFPU.z + v32FPU;
  738. //minGlobalFPU.v.Min(minGlobalFPU_temp.v, maxGlobalFPU_temp.v);
  739. //maxGlobalFPU.v.Max(minGlobalFPU_temp.v, maxGlobalFPU_temp.v);
  740. //Сохраняем для GPU
  741. gpuData->data[0].x = v00FPU;
  742. gpuData->data[0].y = v10FPU;
  743. gpuData->data[0].z = v20FPU;
  744. gpuData->data[0].w = v30FPU;
  745. gpuData->data[1].x = v01FPU;
  746. gpuData->data[1].y = v11FPU;
  747. gpuData->data[1].z = v21FPU;
  748. gpuData->data[1].w = v31FPU;
  749. gpuData->data[2].w = v32FPU;
  750. /*
  751. if (GetAsyncKeyState('U') < 0)
  752. {
  753. pRS->DrawSphere(tmp.v * mtxWorld, centerLocalFPU.w);
  754. }
  755. if (GetAsyncKeyState('I') < 0)
  756. {
  757. pRS->DrawMatrix(Matrix(Vector(0.0f), tmp.v * mtxWorld), 0.3f);
  758. pRS->Print(tmp.v * mtxWorld, 100000.0f, 0.0f, 0xFFFFFFFF, "%s", inputBone->name.c_str());
  759. }
  760. if (stricmp (inputBone->name.c_str(), "t21") == 0 || stricmp (inputBone->name.c_str(), "q17") == 0)
  761. {
  762. //centerLocalFPU.xyz не должен быть нулем !!!! какой то баг....
  763. //коробка тоже пустая !!!! надо заново считать !!!
  764. Matrix mBindPos = mtxBindPoseFPU;
  765. mBindPos.Inverse();
  766. Vector ttt = tmp.v * mtxWorld;
  767. Vector ttt2 = mAnimFPU.pos * mtxWorld;
  768. Vector ttt3 = mBindPos.pos * mtxWorld;
  769. pRS->DrawSphere(ttt, centerLocalFPU.w);
  770. pRS->DrawMatrix(Matrix(Vector(0.0f), ttt2), 0.1f);
  771. pRS->DrawMatrix(Matrix(Vector(0.0f), ttt), 0.3f);
  772. pRS->DrawMatrix(Matrix(Vector(0.0f), ttt3), 0.2f);
  773. pRS->DrawLine(ttt2, 0xFFFF0000, ttt, 0xFFFFFFFF);
  774. pRS->DrawLine(ttt3, 0xFF00FF00, ttt, 0xFFFFFFFF);
  775. pRS->Print(ttt, 100000.0f, 0.0f, 0xFFFFFFFF, "%s", inputBone->name.c_str());
  776. pRS->Print(ttt2, 100000.0f, 0.0f, 0xFFFF0000, "%s", inputBone->name.c_str());
  777. pRS->Print(ttt3, 100000.0f, 0.0f, 0xFF00FF00, "%s", inputBone->name.c_str());
  778. }
  779. */
  780. #endif
  781. } else
  782. {
  783. gpuData->data[0] = Vector4(1.0f, 0.0f, 0.0f, 0.0f);
  784. gpuData->data[1] = Vector4(0.0f, 1.0f, 0.0f, 0.0f);
  785. gpuData->data[2].w = 0.0f;
  786. //cachedBoneData->bbSphereCenterGlobalAndRadius = inputBone->bbSphereCenterAndRadius;
  787. //cachedBoneData->bbMaxGlobal = inputBone->bbMax;
  788. //cachedBoneData->bbMinGlobal = inputBone->bbMin;
  789. }
  790. }
  791. #ifdef USE_XBOX_VMX_MATRIXCODE
  792. __stvx(localBoundBoxMin_VMX, pLocalBoundBoxMin, 0);
  793. __stvx(localBoundBoxMax_VMX, pLocalBoundBoxMax, 0);
  794. #endif
  795. //pRS->DrawBox(localBoundBoxAligned->vMin, localBoundBoxAligned->vMax, mtxWorld, 0xFFFF0000);
  796. }
  797. void MeshInstance::SendSkeletonToGPU(subsetAnim * subset, const TTABLEITEM * pTTableLocalToGlobal, dword dwTTableSize) const
  798. {
  799. #ifdef _XBOX
  800. IVBuffer* bonesVB = GMXService::pGS->GetSkinBones_Stream();
  801. Vector4* GMX_skinBones = (Vector4*)bonesVB->Lock();
  802. #else
  803. //Нужен все равно массив, т.к. мы мэпинг делаем в пространство HLSL массива...
  804. static Vector4 GMX_skinBones[225];
  805. #endif
  806. //dword dwSubsetBonesCount = subset->dwBonesCount;
  807. //dword dwGlobalOffset = subset->bonesGlobalOffset;
  808. const TTABLEITEM * __restrict ttable = pTTableLocalToGlobal;
  809. boneGpuData * __restrict bonesGpuData = pBonesGPUdata;
  810. for (dword localBoneIndex = 0; localBoneIndex < dwTTableSize; localBoneIndex++, ttable++)
  811. {
  812. TTABLEITEM globalBoneIdx = *ttable;
  813. const boneGpuData & gpuData = bonesGpuData[globalBoneIdx];
  814. GMX_skinBones[localBoneIndex * 3 + 0] = gpuData.data[0];
  815. GMX_skinBones[localBoneIndex * 3 + 1] = gpuData.data[1];
  816. GMX_skinBones[localBoneIndex * 3 + 2] = gpuData.data[2];
  817. }
  818. #ifdef _XBOX
  819. bonesVB->Unlock();
  820. pRS->SetStreamSource(2, bonesVB);
  821. #else
  822. Vector4 * gpuBonesArray = &GMX_skinBones[0];
  823. MeshInstance::skinBonesVar->SetVector4Array(gpuBonesArray, 225);
  824. #endif
  825. }
  826. void MeshInstance::Draw()
  827. {
  828. #ifndef STOP_DEBUG
  829. if (GMXService::bBlendShapeDebug)
  830. {
  831. dword index = INVALID_OFFSET;
  832. dword dwKeysCount = ARRSIZE(debugKeys);
  833. for (dword i = 0; i < dwKeysCount; i++)
  834. {
  835. if (api->DebugKeyState(debugKeys[i]))
  836. {
  837. index = i;
  838. break;
  839. }
  840. }
  841. for (dword j = 0; j < msh.dwBlendShapeTargetsCount; j++)
  842. {
  843. float val = 0.0f;
  844. if (j == index) val = 1.0f;
  845. SetBlendShapeMorphTargetWeight(j , val);
  846. }
  847. debugDrawBlendShapes();
  848. }
  849. #endif
  850. if (bFrustumCull && GMXService::pGS->GetGlobalFrustumCullStateFast())
  851. {
  852. const GMXBoundSphere & bsphere = GetLocalBoundSphere();
  853. //const GMXBoundBox & bbox = GetLocalBound();
  854. const Plane* frustumPlanes = NGRender::pRS->GetFrustumFast();
  855. #ifdef _XBOX
  856. Vector sphWorldCenter = bsphere.vCenter * mtxWorld;
  857. XMVECTOR sphereWorldCenter = XMLoadFloat3A((CONST XMFLOAT3A*)&sphWorldCenter.x);
  858. XMVECTOR sphereRadis = XMVectorReplicate(bsphere.fRadius);
  859. if (FrustumSphereTest(frustumPlanes, sphereWorldCenter, sphereRadis) == FALSE)
  860. {
  861. return;
  862. }
  863. #else
  864. Vector sphereWorldCenter = bsphere.vCenter * mtxWorld;
  865. if (FrustumSphereTest(frustumPlanes, sphereWorldCenter, bsphere.fRadius) == FALSE)
  866. {
  867. return;
  868. }
  869. #endif
  870. }
  871. if (!GMXService::pGS->IsSuppressSceneSetUserColor())
  872. {
  873. GMXService::pGS->SetUserColor(clrUser);
  874. }
  875. GMXService::pGS->SetCustomAlphaRef(sceneAlphaRef);
  876. pRS->SetWorld(mtxWorld);
  877. SetupShadow(bShadowReceive);
  878. dword dwOffset = 0;
  879. if (GMXService::pGS->GetRenderMode_Fast())
  880. {
  881. dwOffset = 2;
  882. }
  883. DRAW_FUNCTION drawFunc = drawFunctions[dwCurrentDrawFunc + dwOffset];
  884. (this->*drawFunc)();
  885. #ifndef STOP_DEBUG
  886. if (GMXService::bGeometryDebug)
  887. {
  888. const GMXBoundBox & box = GetLocalBound();
  889. NGRender::pRS->DrawBox(box.vMin, box.vMax, mtxWorld);
  890. Matrix mtx;
  891. GMXHANDLE h;
  892. for (dword i = 0; i < msh.dwLocatorsCount; i++)
  893. {
  894. locator & loc = msh.pLocators.ptr[i];
  895. h.index = (i + 1);
  896. GetNodeWorldTransform(h, mtx);
  897. NGRender::pRS->DrawMatrix(mtx, 0.1f);
  898. NGRender::pRS->Print(mtx.pos, 100000.0f, 0.0f, 0xFFFFFFFF, "%s", loc.name.c_str());
  899. }
  900. }
  901. #endif
  902. }
  903. void MeshInstance::ForceRelease ()
  904. {
  905. Assert(refCount > 0);
  906. refCount = 1;
  907. Release ();
  908. }
  909. bool MeshInstance::Release ()
  910. {
  911. Assert(refCount > 0);
  912. refCount--;
  913. if (refCount <= 0)
  914. {
  915. GMXService::pGS->freeMeshInstance(this);
  916. return true;
  917. }
  918. return false;
  919. }
  920. void MeshInstance::AddRef ()
  921. {
  922. refCount++;
  923. }
  924. bool MeshInstance::IsAnimated ()
  925. {
  926. return (msh.bAnimated != 0);
  927. }
  928. const Color& MeshInstance::GetUserColor()
  929. {
  930. return clrUser;
  931. }
  932. const Matrix& MeshInstance::GetTransform ()
  933. {
  934. return mtxWorld;
  935. }
  936. IAnimationTransform* MeshInstance::GetAnimationTransform ()
  937. {
  938. if (pAnimation == NULL)
  939. {
  940. return NULL;
  941. }
  942. return pAnimation->Clone();
  943. }
  944. bool MeshInstance::GetDynamicLightState ()
  945. {
  946. return (bDynamicLight != FALSE);
  947. }
  948. bool MeshInstance::GetShadowReceiveState ()
  949. {
  950. IShadowsService* shadwSRV = GMXService::pGS->GetShadowSrv();
  951. if (!shadwSRV)
  952. {
  953. return false;
  954. }
  955. if (!shadwSRV->IsActiveShadowMap())
  956. {
  957. return false;
  958. }
  959. return (bShadowReceive != FALSE);
  960. }
  961. void MeshInstance::SetTransform (const Matrix& mWorld)
  962. {
  963. mtxWorld = mWorld;
  964. }
  965. void MeshInstance::SetAnimationFile (const char* szAnimationFile)
  966. {
  967. if (!msh.bAnimated || pAnimManager == NULL)
  968. {
  969. return;
  970. }
  971. CreateAnimation(pAnimManager, szAnimationFile);
  972. }
  973. void MeshInstance::SetBoneAlpha (dword dwBoneAnimationIdx, float fAlpha)
  974. {
  975. if (!msh.bAnimated)
  976. {
  977. return;
  978. }
  979. if (dwBoneAnimationIdx >= 255)
  980. {
  981. return;
  982. }
  983. long idxGeom = pAnimToGeom_TranslateTable[dwBoneAnimationIdx];
  984. if (idxGeom >= 0)
  985. {
  986. pBonesGPUdata[idxGeom].data[2].x = fAlpha;
  987. }
  988. }
  989. void MeshInstance::SetBoneScale (dword dwBoneAnimationIdx, float fScale)
  990. {
  991. if (!msh.bAnimated)
  992. {
  993. return;
  994. }
  995. if (dwBoneAnimationIdx >= 255)
  996. {
  997. return;
  998. }
  999. long idxGeom = pAnimToGeom_TranslateTable[dwBoneAnimationIdx];
  1000. if (idxGeom >= 0)
  1001. {
  1002. pBonesGPUdata[idxGeom].data[2].y = fScale;
  1003. }
  1004. }
  1005. void MeshInstance::SetManagers (IAnimationScene * animationScene, IParticleManager* pManager, ISoundScene* pSound)
  1006. {
  1007. pAnimManager = animationScene;
  1008. pParticleManager = pManager;
  1009. pSoundManager = pSound;
  1010. CreateParticles();
  1011. }
  1012. void MeshInstance::SetUserColor(const Color& clr)
  1013. {
  1014. clrUser = clr;
  1015. }
  1016. void MeshInstance::SetFloatAlphaReference(float alphaRef)
  1017. {
  1018. sceneAlphaRef = alphaRef;
  1019. }
  1020. void MeshInstance::SetDynamicLightState (bool bState)
  1021. {
  1022. bDynamicLight = bState;
  1023. SelectDrawFunction();
  1024. }
  1025. void MeshInstance::SelectDrawFunction()
  1026. {
  1027. if (msh.bAnimated == 0)
  1028. {
  1029. if (bDynamicLight == 0)
  1030. {
  1031. dwCurrentDrawFunc = 0;
  1032. } else
  1033. {
  1034. dwCurrentDrawFunc = 1;
  1035. }
  1036. } else
  1037. {
  1038. if (bDynamicLight == 0)
  1039. {
  1040. dwCurrentDrawFunc = 4;
  1041. } else
  1042. {
  1043. dwCurrentDrawFunc = 5;
  1044. }
  1045. }
  1046. }
  1047. void MeshInstance::SetShadowReceiveState (bool bState)
  1048. {
  1049. bShadowReceive = bState;
  1050. }
  1051. IAnimationScene * MeshInstance::AnimationScene()
  1052. {
  1053. return pAnimManager;
  1054. }
  1055. IParticleManager* MeshInstance::Particles()
  1056. {
  1057. return pParticleManager;
  1058. }
  1059. ISoundScene* MeshInstance::Sound()
  1060. {
  1061. return pSoundManager;
  1062. }
  1063. const GMXBoundSphere & MeshInstance::GetLocalBoundSphere()
  1064. {
  1065. if (msh.bAnimated && pAnimation)
  1066. {
  1067. dword dwServiceCacheIdx = GMXService::pGS->getCacheFrame();
  1068. if (dwServiceCacheIdx == dwLocalBSUpdateCacheIdx)
  1069. {
  1070. return *localBoundSphereAligned;
  1071. }
  1072. UpdateAnimation(pAnimation);
  1073. Vector vExtents = (localBoundBoxAligned->vMax - localBoundBoxAligned->vMin) * 0.5f;
  1074. localBoundSphereAligned->vCenter = localBoundBoxAligned->vMin + vExtents;
  1075. localBoundSphereAligned->fRadius = vExtents.GetLength();
  1076. dwLocalBSUpdateCacheIdx = dwServiceCacheIdx;
  1077. return *localBoundSphereAligned;
  1078. }
  1079. return msh.staticBoundSphere;
  1080. }
  1081. const GMXBoundSphere & MeshInstance::GetBoundSphere()
  1082. {
  1083. const GMXBoundSphere & localBound = GetLocalBoundSphere();
  1084. globalBoundSphereAligned->vCenter = msh.staticBoundSphere.vCenter * mtxWorld;
  1085. globalBoundSphereAligned->fRadius = msh.staticBoundSphere.fRadius;
  1086. return *globalBoundSphereAligned;
  1087. }
  1088. const GMXBoundBox & MeshInstance::GetLocalBound()
  1089. {
  1090. if (msh.bAnimated && pAnimation)
  1091. {
  1092. UpdateAnimation(pAnimation);
  1093. return *localBoundBoxAligned;
  1094. }
  1095. return msh.staticBoundBox;
  1096. }
  1097. const GMXBoundBox & MeshInstance::GetBound()
  1098. {
  1099. const GMXBoundBox & localBound = GetLocalBound();
  1100. Vector vExtents = (localBound.vMax - localBound.vMin) * 0.5f;
  1101. static Matrix mTempTranspose;
  1102. mTempTranspose.pos = localBound.vMin + vExtents;
  1103. //fixme speed: тут не полное умножение можно по идее...
  1104. //и вообще посмотреть нормальный быстрый алгоритм OBB->AABB
  1105. Matrix mTransform = mTempTranspose * mtxWorld;
  1106. Vector vAABBExtents;
  1107. float v1 = mTransform.m[0][0] * vExtents.x;
  1108. float v2 = mTransform.m[0][1] * vExtents.y;
  1109. float v3 = mTransform.m[0][2] * vExtents.z;
  1110. float v4 = mTransform.m[1][0] * vExtents.x;
  1111. float v5 = mTransform.m[1][1] * vExtents.y;
  1112. float v6 = mTransform.m[1][2] * vExtents.z;
  1113. float v7 = mTransform.m[2][0] * vExtents.x;
  1114. float v8 = mTransform.m[2][1] * vExtents.y;
  1115. float v9 = mTransform.m[2][2] * vExtents.z;
  1116. //fixme speed: это на боксе смерть !! работа через память !!
  1117. ffabs(v1); ffabs(v2); ffabs(v3);
  1118. ffabs(v4); ffabs(v5); ffabs(v6);
  1119. ffabs(v7); ffabs(v8); ffabs(v9);
  1120. vAABBExtents.x = v1+v2+v3;
  1121. vAABBExtents.y = v4+v5+v6;
  1122. vAABBExtents.z = v7+v8+v9;
  1123. Vector vAABBCenter = mTransform.pos;
  1124. globalBoundBoxAligned->vMin = vAABBCenter - vAABBExtents;
  1125. globalBoundBoxAligned->vMax = vAABBCenter + vAABBExtents;
  1126. return *globalBoundBoxAligned;
  1127. }
  1128. GMXHANDLE MeshInstance::FindEntityByHashedString (GMXENTITYTYPE type, const char* szName, dword dwStringHash, dword dwLen)
  1129. {
  1130. locator * entry = msh.entryTable[dwStringHash & (HASH_TABLE_SIZE - 1)].ptr;
  1131. while(entry)
  1132. {
  1133. if (type == GMXET_LOCATOR && entry->desc.type != NODE_TYPE_LOCATOR)
  1134. {
  1135. entry = entry->pHashTableNext.ptr;
  1136. continue;
  1137. }
  1138. if (type == GMXET_LOCATORPARTICLES && entry->desc.type != NODE_TYPE_LOCATORPARTICLES)
  1139. {
  1140. entry = entry->pHashTableNext.ptr;
  1141. continue;
  1142. }
  1143. dword dwEntryHash = entry->name.hashNoCase();
  1144. dword dwEntryLen = entry->name.length();
  1145. if (dwEntryHash == dwStringHash && dwEntryLen == dwLen)
  1146. {
  1147. const char * szEntryName = entry->name.c_str();
  1148. if (_stricmp(szEntryName, szName) == 0)
  1149. {
  1150. return entry->handle;
  1151. }
  1152. }
  1153. entry = entry->pHashTableNext.ptr;
  1154. }
  1155. GMXHANDLE invalidHandle;
  1156. invalidHandle.reset();
  1157. return invalidHandle;
  1158. }
  1159. const Matrix & MeshInstance::GetNodeWorldTransform(GMXHANDLE handle, Matrix & mtx)
  1160. {
  1161. Assert(handle.index >= 1 && handle.index <= msh.dwLocatorsCount);
  1162. const Matrix & mtxNode = GetNodeLocalTransform(handle);
  1163. mtx = mtxNode * mtxWorld;
  1164. return mtx;
  1165. }
  1166. const char* MeshInstance::GetNodeName (GMXHANDLE handle)
  1167. {
  1168. if (handle.isValid())
  1169. {
  1170. Assert(handle.index >= 1 && handle.index <= msh.dwLocatorsCount);
  1171. dword dwLocIndex = (handle.index-1);
  1172. return msh.pLocators.ptr[dwLocIndex].name.c_str();
  1173. }
  1174. return NULL;
  1175. }
  1176. IPhysRigidBody* MeshInstance::CreatePhysicsActor (IPhysicsScene & scene, bool bDynamic)
  1177. {
  1178. if (msh.bAnimated || msh.dwCreatedPhysicMeshesCount == 0)
  1179. {
  1180. return NULL;
  1181. }
  1182. //---------------------------------------------
  1183. Matrix mtxLocalTransform(false);
  1184. IPhysicsScene::MeshInit * pPhysMeshes = (IPhysicsScene::MeshInit*)msh.pCreatedPhysicMeshes.ptr;
  1185. mesh * __restrict geom = msh.pMeshes.ptr;
  1186. dword dwMeshesCount = msh.dwMeshesCount;
  1187. dword dwGlobalIndex = 0;
  1188. for (dword i = 0; i < dwMeshesCount; i++, geom++)
  1189. {
  1190. if (geom->bCollision == 0)
  1191. {
  1192. continue;
  1193. }
  1194. mtxLocalTransform = geom->pTransform.ptr->mtxLocalTransform;
  1195. dword dwSubsets = geom->dwSubsetCount;
  1196. subsetStatic * __restrict subsetStat = geom->pStaticSubsets.ptr;
  1197. for (dword j = 0; j < dwSubsets; j++, subsetStat++)
  1198. {
  1199. if (pPhysMeshes[dwGlobalIndex].mesh)
  1200. {
  1201. assert(dwGlobalIndex < msh.dwCreatedPhysicMeshesCount);
  1202. pPhysMeshes[dwGlobalIndex].mtx = mtxLocalTransform;
  1203. dwGlobalIndex++;
  1204. }
  1205. }
  1206. }
  1207. //---------------------------------------------
  1208. IPhysRigidBody * pActorMesh = scene.CreateMesh(getSourceFile(), getSourceLine(), pPhysMeshes, msh.dwCreatedPhysicMeshesCount, bDynamic);
  1209. return pActorMesh;
  1210. }
  1211. dword MeshInstance::GetBlendShapesCount()
  1212. {
  1213. return msh.dwBlendShapeTargetsCount;
  1214. }
  1215. void MeshInstance::SetBlendShapeMorphTargetWeight (dword dwMorphtargetIndex, float fWeight)
  1216. {
  1217. if (dwMorphtargetIndex >= msh.dwBlendShapeTargetsCount)
  1218. {
  1219. api->Trace("Morph Index = %d, Max Morph Index is = %d. CRITICAL ERROR !!!", dwMorphtargetIndex, msh.dwBlendShapeTargetsCount);
  1220. return;
  1221. }
  1222. Assert(dwMorphtargetIndex < msh.dwBlendShapeTargetsCount);
  1223. Assert(pMorphTargetsWeights);
  1224. CreateBlendShapesIfNeed();
  1225. pMorphTargetsWeights[dwMorphtargetIndex] = fWeight;
  1226. }
  1227. void MeshInstance::SpoilAnimationCache ()
  1228. {
  1229. dword dwSpoiledCacheIdx = (GMXService::pGS->getCacheFrame() - 1);
  1230. dwAnimationUpdateCacheIdx = dwSpoiledCacheIdx;
  1231. dwLocalBSUpdateCacheIdx = dwSpoiledCacheIdx;
  1232. }
  1233. void MeshInstance::SpoilTransformationsCache ()
  1234. {
  1235. dword dwSpoiledCacheIdx = (GMXService::pGS->getCacheFrame() - 1);
  1236. dwTransformationsUpdateCacheIdx = dwSpoiledCacheIdx;
  1237. }
  1238. //Возвращает количество костей, и заполняет указатели информационная часть кости и трансформация кости...
  1239. dword MeshInstance::GetBonesArray(boneDataReadOnly ** boneData, boneMtxInputReadOnly ** boneTransformations)
  1240. {
  1241. if(boneData)
  1242. {
  1243. *boneData = msh.pBonesInfo.ptr;
  1244. }
  1245. if (boneTransformations)
  1246. {
  1247. *boneTransformations = msh.pBonesMatrices.ptr;
  1248. }
  1249. return msh.dwBonesCount;
  1250. }
  1251. void MeshInstance::GetAllLocators(array<GMXHANDLE> & locators)
  1252. {
  1253. locators.Reserve(msh.dwLocatorsCount);
  1254. for (dword i = 0; i < msh.dwLocatorsCount; i++)
  1255. {
  1256. const locator & loc = msh.pLocators.ptr[i];
  1257. locators.Add(loc.handle);
  1258. }
  1259. }
  1260. int MeshInstance::findSubscribedClass (Object* _class)
  1261. {
  1262. for (dword n = 0; n < subscribedToDeletionEvent.Size(); n++)
  1263. {
  1264. if (subscribedToDeletionEvent[n].object == _class) return n;
  1265. }
  1266. return -1;
  1267. }
  1268. void MeshInstance::SubscribeDeletionEvent (Object* _class, GMX_EVENT _method)
  1269. {
  1270. // already subscribed...
  1271. if (findSubscribedClass(_class) != -1) return;
  1272. SubscribeStruct temp;
  1273. temp.event = _method;
  1274. temp.object = _class;
  1275. subscribedToDeletionEvent.Add(temp);
  1276. }
  1277. void MeshInstance::UnSubscribeDeletionEvent (Object* _class)
  1278. {
  1279. int founded = findSubscribedClass(_class);
  1280. if (founded == -1) return;
  1281. subscribedToDeletionEvent.ExtractNoShift(founded);
  1282. }
  1283. void MeshInstance::CreateParticles()
  1284. {
  1285. if (!pParticleManager)
  1286. {
  1287. for (dword i = 0; i < msh.dwLocatorsWithParticlesCount; i++)
  1288. {
  1289. pParticlesPtrCache[i].pSystem = NULL;
  1290. pParticlesPtrCache[i].pMasterLocator.reset();
  1291. }
  1292. return;
  1293. }
  1294. Matrix mWorldTransform;
  1295. locator * __restrict cLocator = msh.pLocators.ptr;
  1296. for (dword i = 0; i < msh.dwLocatorsCount; i++, cLocator++)
  1297. {
  1298. dword dwCachIdx = cLocator->dwParticleCacheIndex;
  1299. if (dwCachIdx == INVALID_OFFSET)
  1300. {
  1301. continue;
  1302. }
  1303. Assert(dwCachIdx < msh.dwLocatorsWithParticlesCount);
  1304. const char * particleSystemName = cLocator->particleName.c_str();
  1305. IParticleSystem* pSystem = pParticleManager->CreateParticleSystemEx(particleSystemName, _FL_);
  1306. if (pSystem)
  1307. {
  1308. GetNodeWorldTransform(cLocator->handle, mWorldTransform);
  1309. pSystem->Teleport(mWorldTransform);
  1310. pSystem->AutoHide(true);
  1311. }
  1312. pParticlesPtrCache[dwCachIdx].pSystem = pSystem;
  1313. pParticlesPtrCache[dwCachIdx].pMasterLocator = cLocator->handle;
  1314. }
  1315. }
  1316. void MeshInstance::DeleteParticles()
  1317. {
  1318. for (dword i = 0; i < msh.dwLocatorsWithParticlesCount; i++)
  1319. {
  1320. MeshParticleOnLocator * particle = &pParticlesPtrCache[i];
  1321. if (particle->pSystem == NULL)
  1322. {
  1323. continue;
  1324. }
  1325. particle->pSystem->Release();
  1326. particle->pMasterLocator.reset();
  1327. particle->pSystem = NULL;
  1328. }
  1329. }
  1330. void MeshInstance::SendDeleteNotifiaction()
  1331. {
  1332. for (int n = 0; n < subscribedToDeletionEvent; n++)
  1333. {
  1334. (subscribedToDeletionEvent[n].object->*subscribedToDeletionEvent[n].event) ();
  1335. }
  1336. subscribedToDeletionEvent.DelAll();
  1337. }
  1338. void MeshInstance::UpdateParticles()
  1339. {
  1340. Matrix mWorldTransform;
  1341. for (dword i = 0; i < msh.dwLocatorsWithParticlesCount; i++)
  1342. {
  1343. MeshParticleOnLocator * particle = &pParticlesPtrCache[i];
  1344. if (particle->pSystem == NULL)
  1345. {
  1346. continue;
  1347. }
  1348. GetNodeWorldTransform(particle->pMasterLocator, mWorldTransform);
  1349. particle->pSystem->SetTransform(mWorldTransform);
  1350. particle->pSystem->CancelHide();
  1351. }
  1352. }
  1353. #ifndef STOP_DEBUG
  1354. void MeshInstance::debugDrawBlendShapes()
  1355. {
  1356. static char tempBar[16];
  1357. Vector vDebugPos = mtxWorld.pos + Vector (0.0f, 2.0f, 0.0f);
  1358. pRS->Print(vDebugPos, 10000.0f, 0, 0xFFFFFFFF, "BlendShapes : %d", msh.dwBlendShapeTargetsCount);
  1359. for (dword i = 0; i < msh.dwBlendShapeTargetsCount; i++)
  1360. {
  1361. const char * visName = "notFound";
  1362. float w = pMorphTargetsWeights[i];
  1363. float _w = w;
  1364. if (_w < 0.0f)
  1365. {
  1366. _w = 0.0f;
  1367. }
  1368. if (_w > 1.0f)
  1369. {
  1370. _w = 1.0f;
  1371. }
  1372. int barCount = (int)(_w * (ARRSIZE(tempBar)-1));
  1373. memset(tempBar, '*', barCount);
  1374. tempBar[barCount] = 0;
  1375. if (i < ARRSIZE(visemesName))
  1376. {
  1377. visName = visemesName[i];
  1378. }
  1379. pRS->Print(vDebugPos, 10000.0f, (float)i + 1.0f, 0xFFFFFFFF, "(%s) %f %s", visName, w, tempBar);
  1380. }
  1381. }
  1382. #endif
  1383. const char* MeshInstance::GetFileName()
  1384. {
  1385. #ifndef STOP_DEBUG
  1386. return debugName.c_str();
  1387. #else
  1388. return "";
  1389. #endif
  1390. }
  1391. void MeshInstance::CreateBlendShapesIfNeed()
  1392. {
  1393. //Уже создали
  1394. if (blendShapeMixer != NULL)
  1395. {
  1396. return;
  1397. }
  1398. //Не анимированный меш
  1399. if (msh.bAnimated == false)
  1400. {
  1401. return;
  1402. }
  1403. //Нет блендшейпных костей
  1404. if (msh.dwBlendShapeBonesCount <= 0)
  1405. {
  1406. return;
  1407. }
  1408. //Нет блендшейп визем
  1409. if (msh.dwBlendShapeTargetsCount <= 0)
  1410. {
  1411. return;
  1412. }
  1413. //Нет установленной анимации
  1414. if (pAnimation == NULL)
  1415. {
  1416. return;
  1417. }
  1418. //Нужна анимация, а не animation transform
  1419. if (!pAnimation->Is(anitype_animation))
  1420. {
  1421. return;
  1422. }
  1423. blendShapeMixer = NEW GMXBlendShapeMixer(msh.dwBlendShapeTargetsCount, pMorphTargetsWeights, msh.pBlendShapeTargets.ptr,
  1424. msh.dwBlendShapeBonesTransformCount, msh.pBlendShapeBonesTransform.ptr, pAnimToGeomBlendShapes_TranslateTable);
  1425. blendShapeMixer->RegisterAnimation(pAnimation, DEFAULT_BLENDSHAPE_LEVEL);
  1426. }