Сделал демку по мотивам этого видео. Использовал ООП, поэтому получилось немного громоздко, так же разделил графическую реализацию, в этой версии реализованы GDI, GDI+. Потом можно добавить например OpenGL. Код для UASM v2.52, используется SSE2, можно опционально SSE3 Физический движок моделирует упругую коллизию шариков, хотя по мне реализация столкновения имеет некоторую погрешность и зависимость к высокому ФПС, т.е. апдейтов за сек, в некоторых случаях маленькие шарики могут пролетать сквозь друг-друга. Для фикса надо реализовать пересечения траекторий. Графический движок использует двойную буферизацию, реализация так себе, насколько позволяет WinAPI, а позволяет он не очень много. На старых ПК больше времени занимает рендер графики. ЗЫ Ещё автор использовал хитрую оптимизацию чтобы уменьшить квадратичную зависимость от кол. шариков, но я забил на это, код и так быстро работает, да слишком большое кол. шариков на сцене портит картинку.
Определение столкновений и моделирование законов физики Как найти столкновения между плоскостью, цилиндром, и сферой. Как иммитировать физику, взрывы.
Апдейт vector2.asm, добавлена поддержка SSE4.1 используется инструкция dppd, вычисление dotproduct Код (ASM): movxmm MACRO dest:req, source:req IFDIFI <dest>,<source> movups dest, source ENDIF ENDM dVec2 union ;(sizeof=16, align=8) xmmword ? struct x real8 ? y real8 ? ends dVec2 ends ;скалярное произведения 3d вектора ;результат возвращается xmm0.0, регистры xmm0, xmm1 не сохраняются dVec2@dotproduct MACRO res_reg:req, vec_this:req, vec:req movxmm xmm0, vec_this IF INSTRUCTIONS__SSEx EQ 3 dVec2@mul xmm0, vec haddpd xmm0, xmm0 ELSEIF INSTRUCTIONS__SSEx EQ 4 dppd xmm0, vec, 110011b ELSE dVec2@mul xmm0, vec movsd xmm1, xmm0 ; xmm1.x = x shufpd xmm0, xmm0, 11b ; копируем 1-й элемент в 0-й элемент addsd xmm0, xmm1 ; = x + y ENDIF movxmm res_reg, xmm0 ENDM dVec2@magnitude MACRO res_reg:req, vec_this:req movxmm xmm0, vec_this IF INSTRUCTIONS__SSEx EQ 3 mulpd xmm0, xmm0 haddpd xmm0, xmm0 ELSEIF INSTRUCTIONS__SSEx EQ 4 dppd xmm0, xmm0, 110011b ELSE mulpd xmm0, xmm0 movsd xmm1, xmm0 ; xmm1.x = x shufpd xmm0, xmm0, 11b ; копируем 1-й элемент в 0-й элемент addsd xmm0, xmm1 ; x + y ENDIF sqrtsd res_reg, xmm0 ENDM dVec2@normalize MACRO vec_this:req dVec2@magnitude xmm1, vec_this movsd xmm0, CFP8(1.0) divsd xmm0, xmm1 shufpd xmm0, xmm0, 00b movxmm xmm1, vec_this mulpd xmm0, xmm1 ENDM dVec2@set_length MACRO res_reg:req, vec_this:req, len:req dVec2@magnitude xmm0, vec_this movsd xmm1, len divsd xmm1, xmm0 ;=len/magnitude(); shufpd xmm1, xmm1, 00b movxmm res_reg, vec_this mulpd res_reg, xmm1 ;this.mul(len/magnitude()); ENDM dVec2@opr2or3 MACRO comand:req, vec0:req, vec1:req, vec2 IFNB <vec2> movxmm xmm0, vec1 IF ((OPATTR (vec2)) AND REG_EXPR) comand xmm0, vec2 ELSE movxmm xmm1, vec2 comand xmm0, xmm1 ENDIF ELSE movxmm xmm0, vec0 IF ((OPATTR (vec1)) AND REG_EXPR) comand xmm0, vec1 ELSE movxmm xmm1, vec1 comand xmm0, xmm1 ENDIF ENDIF movxmm vec0, xmm0 ENDM dVec2@mul MACRO vec0:req, vec1:req, vec2 dVec2@opr2or3 mulpd, vec0, vec1, vec2 ENDM dVec2@div MACRO vec0:req, vec1:req, vec2 dVec2@opr2or3 divpd, vec0, vec1, vec2 ENDM dVec2@add MACRO vec0:req, vec1:req, vec2 dVec2@opr2or3 addpd, vec0, vec1, vec2 ENDM dVec2@sub MACRO vec0:req, vec1:req, vec2 dVec2@opr2or3 subpd, vec0, vec1, vec2 ENDM Добавить в начале ElasticCollisions.asm INSTRUCTIONS__SSEx = 4 ;2 - SSE2, 3 - SSE3, 4 - SSE4.1