I haven't done any assembly coding yet, but I have 4 versions of the intersection code.
Two witch use your vector math, two with inlined math. Each a version with and without backfaceculling.
With backfaceculling only Objects ( like a cube ) work fine, because you only see the triangle from one side, and it only casts a shadow to one side.
Without backfaceculling you get in trouble with the normal vector, because it points in the wrong direction, when you look from behind.
Maybe you should use the "TestBool=#InPrimitive" trick from your refraction routine to flip the normal vector.
I have prepared the non backfaceculling procedures for that. You just have to uncommend the corresponding line and clear the one before.
And here it goes :
Code: Select all
; Moller-Trumbore algorithm, inline version.
Procedure.f TestTriangle(*Origin.xyz,*Direction.xyz,*Triangle.Object)
spana.xyz
spanb.xyz
PVec.xyz
TVec.xyz
QVec.xyz
TestBool=#Miss
*Tri.Triangle = *Triangle\Primitive ; Nicer and faster than PeekF
spana\x = *Tri\v2\x - *Tri\v1\x
spana\y = *Tri\v2\y - *Tri\v1\y
spana\z = *Tri\v2\z - *Tri\v1\z
spanb\x = *Tri\v3\x - *Tri\v1\x
spanb\y = *Tri\v3\y - *Tri\v1\y
spanb\z = *Tri\v3\z - *Tri\v1\z
PVec\x = *Direction\y * spanb\z - *Direction\z * spanb\y
PVec\y = *Direction\z * spanb\x - *Direction\x * spanb\z
PVec\z = *Direction\x * spanb\y - *Direction\y * spanb\x
Det.f = spana\x * PVec\x + spana\y * PVec\y + spana\z * PVec\z
If Det > #EPSILON ; Frontfacing
TVec\x = *Origin\x - *Tri\v1\x
TVec\y = *Origin\y - *Tri\v1\y
TVec\z = *Origin\z - *Tri\v1\z
U.f = TVec\x * PVec\x + TVec\y * PVec\y + TVec\z * PVec\z
If U < 0.0 Or U > Det
ProcedureReturn 0.0
EndIf
QVec\x = TVec\y * spana\z - TVec\z * spana\y
QVec\y = TVec\z * spana\x - TVec\x * spana\z
QVec\z = TVec\x * spana\y - TVec\y * spana\x
V.f = *Direction\x * QVec\x + *Direction\y * QVec\y + *Direction\z * QVec\z
If V < 0.0 Or U + V > Det
ProcedureReturn 0.0
EndIf
TestBool=#Hit
ElseIf Det < #EPSILON ; Backfacing
TVec\x = *Origin\x - *Tri\v1\x
TVec\y = *Origin\y - *Tri\v1\y
TVec\z = *Origin\z - *Tri\v1\z
U.f = TVec\x * PVec\x + TVec\y * PVec\y + TVec\z * PVec\z
If U > 0.0 Or U < Det
ProcedureReturn 0.0
EndIf
QVec\x = TVec\y * spana\z - TVec\z * spana\y
QVec\y = TVec\z * spana\x - TVec\x * spana\z
QVec\z = TVec\x * spana\y - TVec\y * spana\x
V.f = *Direction\x * QVec\x + *Direction\y * QVec\y + *Direction\z * QVec\z
If V > 0.0 Or U + V < Det
ProcedureReturn 0.0
EndIf
TestBool=#Hit
; TestBool=#InPrimitive
Else ; ray parallel triangle
ProcedureReturn 0.0
EndIf
InvDet.f = 1.0 / Det
t.f = (spanb\x * QVec\x + spanb\y * QVec\y + spanb\z * QVec\z) * InvDet
; U = InvDet * U ; texture coordinates
; V = InvDet * V ;
ProcedureReturn t
EndProcedure
; Moller-Trumbore algorithm, inline version. With backface culling
Procedure.f TestTriangleBFC(*Origin.xyz,*Direction.xyz,*Triangle.Object)
spana.xyz
spanb.xyz
PVec.xyz
TVec.xyz
QVec.xyz
TestBool=#Miss
*Tri.Triangle = *Triangle\Primitive ; Nicer and faster than PeekF
spana\x = *Tri\v2\x - *Tri\v1\x
spana\y = *Tri\v2\y - *Tri\v1\y
spana\z = *Tri\v2\z - *Tri\v1\z
spanb\x = *Tri\v3\x - *Tri\v1\x
spanb\y = *Tri\v3\y - *Tri\v1\y
spanb\z = *Tri\v3\z - *Tri\v1\z
PVec\x = *Direction\y * spanb\z - *Direction\z * spanb\y
PVec\y = *Direction\z * spanb\x - *Direction\x * spanb\z
PVec\z = *Direction\x * spanb\y - *Direction\y * spanb\x
Det.f = spana\x * PVec\x + spana\y * PVec\y + spana\z * PVec\z
If Det < #EPSILON ; backfacing or ray parallel triangle
ProcedureReturn 0.0
EndIf
TVec\x = *Origin\x - *Tri\v1\x
TVec\y = *Origin\y - *Tri\v1\y
TVec\z = *Origin\z - *Tri\v1\z
U.f = TVec\x * PVec\x + TVec\y * PVec\y + TVec\z * PVec\z
If U < 0.0 Or U > Det
ProcedureReturn 0.0
EndIf
QVec\x = TVec\y * spana\z - TVec\z * spana\y
QVec\y = TVec\z * spana\x - TVec\x * spana\z
QVec\z = TVec\x * spana\y - TVec\y * spana\x
V.f = *Direction\x * QVec\x + *Direction\y * QVec\y + *Direction\z * QVec\z
If V < 0.0 Or U + V > Det
ProcedureReturn 0.0
EndIf
InvDet.f = 1.0 / Det
TestBool=#Hit
t.f = (spanb\x * QVec\x + spanb\y * QVec\y + spanb\z * QVec\z) * InvDet
; U = InvDet * U ; texture coordinates
; V = InvDet * V ;
ProcedureReturn t
EndProcedure
; Moller-Trumbore algorithm, prototype version. Just to get going.
Procedure.f TestTriangleProto(*Origin.xyz,*Direction.xyz,*Triangle.Object)
spana.xyz
spanb.xyz
PVec.xyz
TVec.xyz
QVec.xyz
TestBool=#Miss
*Tri.Triangle = *Triangle\Primitive ; Nicer and faster than PeekF
VectorSubtract(*Tri\v2,*Tri\v1,spana) ; This could easily be done per frame, or at creation time.
VectorSubtract(*Tri\v3,*Tri\v1,spanb) ; You could store spana / spanb instead of v2 / v3, because you don't need them.
VectorCrossMuiltply(*Direction,spanb,PVec)
Det.f = VectorDotProduct(spana,PVec)
If Det > #EPSILON ; Frontfacing
VectorSubtract(*Origin,*Tri\v1,TVec)
U.f = VectorDotProduct(TVec,PVec)
If U < 0.0 Or U > Det
ProcedureReturn 0.0
EndIf
VectorCrossMuiltply(TVec,spana,QVec)
V.f = VectorDotProduct(*Direction,QVec)
If V < 0.0 Or U + V > Det
ProcedureReturn 0.0
EndIf
TestBool=#Hit
ElseIf Det < #EPSILON ; Backfacing
VectorSubtract(*Origin,*Tri\v1,TVec)
U.f = VectorDotProduct(TVec,PVec)
If U > 0.0 Or U < Det
ProcedureReturn 0.0
EndIf
VectorCrossMuiltply(TVec,spana,QVec)
V.f = VectorDotProduct(*Direction,QVec)
If V > 0.0 Or U + V < Det
ProcedureReturn 0.0
EndIf
TestBool=#Hit
; TestBool=#InPrimitive
Else ; ray parallel triangle
ProcedureReturn 0.0
EndIf
InvDet.f = 1.0 / Det
t.f = VectorDotProduct(spanb,QVec) * InvDet
; U = InvDet * U ; texture coordinates
; V = InvDet * V ;
ProcedureReturn t
EndProcedure
; Moller-Trumbore algorithm, prototype version. Just to get going. With backface culling
Procedure.f TestTriangleBFCProto(*Origin.xyz,*Direction.xyz,*Triangle.Object)
spana.xyz
spanb.xyz
PVec.xyz
TVec.xyz
QVec.xyz
TestBool=#Miss
*Tri.Triangle = *Triangle\Primitive ; Nicer and faster than PeekF
VectorSubtract(*Tri\v2,*Tri\v1,spana) ; This could easily be done per frame, or at creation time.
VectorSubtract(*Tri\v3,*Tri\v1,spanb) ; You could store spana / spanb instead of v2 / v3, because you don't need them.
VectorCrossMuiltply(*Direction,spanb,PVec)
Det.f = VectorDotProduct(spana,PVec)
If Det < #EPSILON ; backfacing or ray parallel triangle
ProcedureReturn 0.0
EndIf
VectorSubtract(*Origin,*Tri\v1,TVec)
U.f = VectorDotProduct(TVec,PVec)
If U < 0.0 Or U > Det
ProcedureReturn 0.0
EndIf
VectorCrossMuiltply(TVec,spana,QVec)
V.f = VectorDotProduct(*Direction,QVec)
If V < 0.0 Or U + V > Det
ProcedureReturn 0.0
EndIf
InvDet.f = 1.0 / Det
TestBool=#Hit
t.f = VectorDotProduct(spanb,QVec) * InvDet
; U = InvDet * U ; texture coordinates
; V = InvDet * V ;
ProcedureReturn t
EndProcedure
Have fun.
PS: You shouldn't have problems integrating them, because i have used all your conventions. But if you get in trouble, just ask.
