피직 트랜스폼(캐릭터 스키닝) 64비트 SSE버젼 코드

소스코드

————————————————————————————————————————————————

<physiq_transform_x64.asm>

————————————————————————————————————————————————
INCLUDE math_type_x64.inc
.code
;void __stdcall PhysiqueTransformPosAndNormalAndUV(BYTE* pVertexResult,PHYSIQUE_VERTEX* pPhyVertex,DWORD dwVertexNum,DWORD dwSize,MATRIX4* pMatrixEntry)
PhysiqueTransformPosAndNormalAndUV PROC pVertexResult:QWORD , pPhyVertex:QWORD , dwVertexNum:QWORD , dwSize:QWORD , pMatrixEntry:QWORD
local   v3Normal : VECTOR4
local   v3Tangent : VECTOR4

; backup xmm6
sub   rsp,32
movups  [rsp+0],xmm6
movups  [rsp+16],xmm7

mov    qword ptr[rbp+16],rcx
mov    qword ptr[rbp+24],rdx
mov    qword ptr[rbp+32],r8
mov    qword ptr[rbp+40],r9

 mov   rcx,dwVertexNum
or   rcx,rcx
jz   lb_return
 mov   r10,pPhyVertex
mov   r8,pVertexResult; pVertexResult
lb_loop_physique_num:
xorps  xmm3,xmm3     ; v3Result
movups  v3Normal,xmm3    ; v3Normal
movups  v3Tangent,xmm3    ; v3Tangent
mov   rax,qword ptr[r10+BONE_ENTRY_OFFSE_IN_PHYVERTEX]  ; bone entry
movzx  rcx,byte ptr[r10+BONE_NUM_OFFSE_IN_PHYVERTEX]   ; pPhyVertex->bBonesNum
 ; 아무곳에도 어싸인되지 않은 버텍스 처리
xor   rdx,rdx
mov   edx,dword ptr[rax]   ; pBone->dwBoneIndex
cmp   edx,-1
jz   lb_write
lb_loop_bones_num:
 xor   rdx,rdx        ; rdx = pBone->dwBoneIndex(matrix index)
mov   edx,dword ptr[rax]     ;

movups  xmm0,[r10+POS_OFFSET_IN_PHYVERTEX] ; pPhyVertex->v3Offset
shl   rdx,6        ; matrix size = 64bytes
add   rdx,pMatrixEntry     ; matrix entry

 movups  xmm4,[rdx]  ; load matrix 1 line
movups  xmm5,[rdx+16] ; load matrix 2 line
movups  xmm6,[rdx+32] ; load matrix 3 line
movups  xmm7,[rdx+48] ; load matrix 4 line
 movaps  xmm1,xmm0  ; src vector
shufps  xmm1,xmm1,0  ; x x x x
mulps  xmm1,xmm4  ; 1 line ok
movaps  xmm2,xmm0  ; src vector
shufps  xmm2,xmm2,85 ; y y y y
mulps  xmm2,xmm5  ; 2 line ok
 addps  xmm1,xmm2
 movaps  xmm2,xmm0  ; src vector
shufps  xmm2,xmm2,170 ; z z z z
mulps  xmm2,xmm6  ; 3 line ok

addps  xmm1,xmm2
addps  xmm1,xmm7

; 여기서부터 탄젠트 벡터 계산
; LOAD VECTOR
movlps  xmm0,qword ptr[r10+TANGENT_OFFSET_IN_PHYVERTEX]   ; pPhyVertex->v3Tangent
movss  xmm2,dword ptr[r10+TANGENT_OFFSET_IN_PHYVERTEX+8]
movlhps  xmm0,xmm2
 movaps  xmm2,xmm0  ; src normal
shufps  xmm2,xmm2,0  ; x x x x
mulps  xmm2,xmm4  ; 1 line ok
 movaps  xmm7,xmm0  ; src normal
shufps  xmm7,xmm7,85 ; y y y y
mulps  xmm7,xmm5  ; 2 line ok
 addps  xmm2,xmm7
 movaps  xmm7,xmm0  ; src normal
shufps  xmm7,xmm7,170 ; z z z z
mulps  xmm7,xmm6  ; 3 line ok
 addps  xmm2,xmm7
 movss  xmm0,dword ptr[rax+4] ; bone->fWeight
shufps  xmm0,xmm0,0  ; xmm0 = fWeight | fWeight | fWeight | fWeight

; xmm2 = ?  | tz | ty | tx
movups  xmm7,v3Tangent
mulps  xmm2,xmm0  ; v3Tangent = (v3Offeset[0] * fWeight) + (v3Offeset[1] * fWeight) + (v3Offeset[2] * fWeight) …
addps  xmm7,xmm2

 movups  v3Tangent,xmm7
 ; 여기서부터 노멀계산..
; LOAD VECTOR
movlps xmm0,qword ptr[r10+NORMAL_OFFSET_IN_PHYVERTEX]   ; pPhyVertex->v3Normal
movss xmm2,dword ptr[r10+NORMAL_OFFSET_IN_PHYVERTEX+8]
movlhps xmm0,xmm2
 movaps  xmm2,xmm0  ; src normal
shufps  xmm2,xmm2,0  ; x x x x
mulps  xmm2,xmm4  ; 1 line ok
 movaps  xmm7,xmm0  ; src normal
shufps  xmm7,xmm7,85 ; y y y y
mulps  xmm7,xmm5  ; 2 line ok
 addps  xmm2,xmm7
 movaps  xmm7,xmm0  ; src normal
shufps  xmm7,xmm7,170 ; z z z z
mulps  xmm7,xmm6  ; 3 line ok
 addps  xmm2,xmm7
; xmm1 = ? | z | y | x

movss  xmm0,dword ptr[rax+4] ; bone->fWeight
shufps  xmm0,xmm0,0  ; xmm0 = fWeight | fWeight | fWeight | fWeight

mulps  xmm1,xmm0  ; v3Result = (v3Offeset[0] * fWeight) + (v3Offeset[1] * fWeight) + (v3Offeset[2] * fWeight) …
addps  xmm3,xmm1

 ; xmm2 = ?  | nz | ny | nx
movups  xmm7,v3Normal
mulps  xmm2,xmm0  ; v3Normal = (v3Offeset[0] * fWeight) + (v3Offeset[1] * fWeight) + (v3Offeset[2] * fWeight) …
addps  xmm7,xmm2
movups  v3Normal,xmm7
 add   rax,BONE_LITE_SIZE
dec   rcx
jnz   lb_loop_bones_num
lb_write:
movhlps  xmm0,xmm3   ; z
movlps  qword ptr[r8],xmm3   ; write x,y
movss  dword ptr[r8+8],xmm0  ; write z
 ; 노멀 써넣기
movups  xmm1,v3Normal  ; v3Normal.xy
movhlps  xmm2,xmm1   ; v3Normal.z

movlps  qword ptr[r8+12],xmm1
movss  dword ptr[r8+12+8],xmm2

 ; uv 써넣기
mov   rax,qword ptr[r10+TEXCOORD_OFFSET_IN_PHYVERTEX]
mov   qword ptr[r8+12+8+4],rax   ; u,v
 ; tangent 써넣기
movups  xmm1,v3Tangent  ; v3Tangent.xy
movhlps  xmm2,xmm1   ; v3Tangent.z

movlps  qword ptr[r8+12+8+8+4],xmm1
movss  dword ptr[r8+12+8+8+12],xmm2

dec   dwVertexNum
jz   lb_return

add   r10,PHYSIQUE_VERTEX_SIZE_X64
add   r8,dwSize
jmp   lb_loop_physique_num
lb_return:
 ; restore xmm6
movups  xmm6,[rsp+0]
movups  xmm7,[rsp+16]
add   rsp,32

ret
PhysiqueTransformPosAndNormalAndUV ENDP

end
—————————————————————————————————————————-
<math_type_x64.inc>
—————————————————————————————————————————-
VECTOR3 STRUCT
x  REAL4  ?
y  REAL4  ?
z  REAL4  ?
VECTOR3 ENDS
VECTOR4 STRUCT
x  REAL4  ?
y  REAL4  ?
z  REAL4  ?
w  REAL4  ?
VECTOR4 ENDS
MOVING_SPHERE STRUCT
From  VECTOR3  <>
fRadius  REAL4  ?
Velocity VECTOR3  <>

MOVING_SPHERE ENDS

VECTOR3_SIZE    EQU 12
PLANE_D_OFFSET    EQU 12
PHYSIQUE_VERTEX_SIZE_X64  EQU  56
BONE_LITE_SIZE     EQU  12
BONE_NUM_OFFSE_IN_PHYVERTEX  EQU  44
BONE_ENTRY_OFFSE_IN_PHYVERTEX EQU  48
POS_OFFSET_IN_PHYVERTEX   EQU  0
NORMAL_OFFSET_IN_PHYVERTEX  EQU  12
TANGENT_OFFSET_IN_PHYVERTEX  EQU  24
TEXCOORD_OFFSET_IN_PHYVERTEX EQU  36

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중